move_as_tuple
とか?
使えたとしても forward_as_tuple と書くのが今度は面倒そう()
構文解析については詳しくないので、 https://ja.wikipedia.org/wiki/LR%E6%B3%95 を読んだのですが、この記事中に
多くのプログラミング言語がLR法(およびそれを一部改変したもの)で構文解析できる。例外として、C++とPerlがある。
との記述がありますね。
A * B ;
とあった際にこの文だけではA
とB
の乗算なのかA*
型の変数B
の宣言なのか区別が付けられないので、一般的な構文解析が出来ない、とどこかで読んだ気がします。
揚げ足を取るような読み方すると、まずn4296 [dcl.ref]/5に
A reference shall be initialized to refer to a valid object or function. [ Note: in particular, a null reference cannot exist in a well-defined program, because the only way to create such a reference would be to bind it to the “object” obtained by indirection through a null pointer, which causes undefined behavior.
というのがあって、じゃぁreferって何ってなるとn4296 [expr.unary.op]/1には
The unary * operator performs indirection: the expression to which it is applied shall be a pointer to an object type, or a pointer to a function type and the result is an lvalue referring to the object or function to which the expression points.
とあるので、nullptrの位置にvalid objectがないことを示せればなんとかUBに持ち込めそう
op->*
とop[]
に関してはそれぞれop.*
とop*
へのequivalenceであることが示されているので割愛
お、確かに、n4296 [conv.ptr]/1だと
A null pointer constant is an integer literal (2.13.2) with value zero or a prvalue of type std::nullptr_t.
A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type
and is distinguishable from every other value of object pointer or function pointer type.
と書いてあるだけで確かにnull pointer valueが0であるとは規定していないな
vector<T>::data()
を使えばよいですけど、 C++03 だと data()
がなくて &vec[0]
とか &(*vec.begin())
とか書いてるコードも多かったでしょうし。
おぉ! CWG issue 232 は見落としていました! ありがとうございます! 現在の方向性は, indirection は許容して lvalue-to-rvalue conversion の段階で U.B. にしよう,ということですか.だとすると,関連する疑問であった
class X {
void f();
};
int main() {
X *p = nullptr;
p->f();
}
は X::f で this が指している empty lvalue に対して lvalue-to-rvalue conversion が走らない限り完全に規格に準拠した well-defined program (ということに将来的にはなりそう)ということですか.