decltypeが括弧あるとかないとかで色々
n2914 7.1.6.2.4
The type denoted by decltype(e) is defined as follows:
- if e is an unparenthesized id-expression or a class member access (5.2.5), decltype(e) is the type of the entity named by e. If there is no such entity, or if e names a set of overloaded functions, the program is ill-formed;
- otherwise, if e is a function call (5.2.2) or an invocation of an overloaded operator (parentheses around e are ignored), decltype(e) is the return type of the statically chosen function;
- otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;
- otherwise, decltype(e) is the type of e.
The operand of the decltype specifier is an unevaluated operand (Clause 5).
訳というか、私の日本語による解釈
decltype(e) が示す型は、次のようにして決まる:
- e が、括弧で囲われていない、 id-expression かクラスメンバへのアクセス (5.2.5) であれば、decltype(e) は、e と名付けられた実体の型である。実体がなかったり、オーバーロードされた関数名であった場合、プログラムは ill-formed である。
- もしくは、e が関数呼び出し (5.2.2) かオーバーロードされた演算子による評価(e の周囲の括弧は無視する)であれば、decltype(e) は、オーバーロードを解決していずれかに決定した関数の戻り値の型である。
- もしくは、e が左辺値であれば、decltype(e) は T& である。T は e の型である。
- もしくは、decltype(e) は、e の型である。
decltype修飾子のオペランドは、評価されない。
「e と名付けられた実体の型」ってつまり、e の宣言で出てきた型ってことでいいの?
int a = 42; int const & r = a; int const * p = &a; int const f(); decltype(a) // 1 int decltype((a)) // 3 int & decltype(f()) // 2 int const decltype((f())) // 2 int const decltype(*p) // 4 int const & decltype(const_cast<int &>(r)) // 3 int & decltype(const_cast<int>(*p)++) // 4 int decltype(static_cast<double>(a)) // 4 double decltype(sizeof(int)) // 4 size_t // 右辺値参照が絡んでくる場合 int && g(); int && rr = std::move(a); decltype(rr) // 1 int && decltype((rr)) // 3 int & decltype(static_cast<int &&>(rr)) // 4 int && decltype(g()) // 2 int &&
こんなような…
追記:
コメント欄でいただいた指摘による修正と、右辺値参照が絡む場合を追加