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) が示す型は、次のようにして決まる:

  1. e が、括弧で囲われていない、 id-expression かクラスメンバへのアクセス (5.2.5) であれば、decltype(e) は、e と名付けられた実体の型である。実体がなかったり、オーバーロードされた関数名であった場合、プログラムは ill-formed である。
  2. もしくは、e が関数呼び出し (5.2.2) かオーバーロードされた演算子による評価(e の周囲の括弧は無視する)であれば、decltype(e) は、オーバーロードを解決していずれかに決定した関数の戻り値の型である。
  3. もしくは、e が左辺値であれば、decltype(e) は T& である。T は e の型である。
  4. もしくは、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 &&

こんなような…

追記:
コメント欄でいただいた指摘による修正と、右辺値参照が絡む場合を追加