14

(回答によって促されます。)

N3290、§7.1.6.2p4を考えると、リストアイテムには番号が付けられていませんが、便宜上、ここでは番号が付けられています。

decltype(e)で示されるタイプは、次のように定義されます。

  1. eが括弧で囲まれていないid式または括弧で囲まれていないクラスメンバーアクセス(5.2.5)の場合、decltype(e)はeで指定されたエンティティのタイプです。そのようなエンティティがない場合、またはeがオーバーロードされた関数のセットに名前を付けている場合、プログラムの形式は正しくありません。
  2. それ以外の場合、eがxvalueの場合、decltype(e)はT &&です。ここで、Tはeのタイプです。
  3. それ以外の場合、eが左辺値の場合、decltype(e)はT&です。ここで、Tはeのタイプです。
  4. それ以外の場合、decltype(e)はeのタイプです。

decltype(0 + 0)で指定されたタイプは何ですか?

項目1は適用されず、2は適用される可能性がありますが、そうでない場合、3は適用されず、4が結果になります。では、xvalueとは何ですか、そして0 + 0はxvalueですか?

§3.10p1:

xvalue(「eXpiring」値)も、通常はその存続期間の終わり近くにあるオブジェクトを参照します(たとえば、そのリソースを移動できるようにするため)。xvalueは、右辺値参照(8.3.2)を含む特定の種類の式の結果です。

§8.3.2にはここで役立つものは何もありませんが、「0+0」には右辺値参照が含まれていないことは知っています。リテラル0は、「xvalueではない右辺値」(§3.10p1)であるprvalueです。「0+0」も優先値だと思います。それが本当なら、「decltype(0 + 0)」はintになります(int &&ではありません)。

私は私の解釈で何かを逃したことがありますか?このコードは整形式ですか?

decltype(0 + 0) x;  // Not initialized.

このコードは、GCC 4.7.020110427およびClang2.9(トランク126116)でコンパイルされます。たとえば、decltypeがint &&型を指定した場合、整形式ではありません。

4

5 に答える 5

10

0 + 0は2つのprvalues(n3290 par。3.10)の式であり、組み込みのを適用します。これは、operator+13.6 / 12に従ってLR operator+(L,R)、であるため、参照ではないものを返す関数です。したがって、式の結果もprvalueになります(3.10による)。

したがって、0 + 0の結果はprvalueであり、0はでありint、したがって0+0の結果はint

于 2011-05-08T02:55:29.880 に答える
5

それは間違いなくintです:

#include <iostream>
#include <typeinfo>

template<typename T>
struct ref_depth
{
        enum { value = 0 };
};

template<typename T>
struct ref_depth<T&>
{
        enum { value = 1 };
};

template<typename T>
struct ref_depth<T&&>
{
        enum { value = 2 };
};

int main() {

  std::cout
    << "int: " << typeid(int).name() << "\n"
       "decltype(0 + 0): " << typeid(decltype(0 + 0)).name() << "\n"
       "int&&: " << typeid(int&&).name() << "\n";
  std::cout 
    << "ref_depth: int: " << ref_depth<int>::value << "\n"
       "ref_depth: decltype(0 + 0): " << ref_depth<decltype(0 + 0)>::value << "\n"
       "ref_depth: int&&: " << ref_depth<int&&>::value << "\n";

}

出力:

int: i
decltype(0 + 0): i
int&&: i
ref_depth: int: 0
ref_depth: decltype(0 + 0): 0
ref_depth: int&&: 2
于 2011-05-08T03:13:16.767 に答える
2

5.19 から[expr.const]、すべてのリテラル定数式は prvalue です。

リテラル定数式は、リテラル型のprvalue コア定数式ですが、ポインター型ではありません。整数定数式は、整数型またはスコープなし列挙型のリテラル定数式です。

したがって、ルール 4 はすべてのリテラル定数式に適用されます。

于 2011-05-30T19:20:08.467 に答える
2

あなたの推論は正しいです。定数のみを含む式は、それ自体が定数です。したがって

decltype(0 + 0) x;

等しい

decltype(0) x;

等しい

int x;
于 2011-05-08T01:02:13.183 に答える
0

GCCは言うint-

コード:

#include <iostream>
#include <typeinfo>

int
main ()
{
  int n;
  decltype(0 + 0) x;
  std::cout << "Type of `n': " << typeid(n).name() << std::endl;
  std::cout << "Type of `x': " << typeid(x).name() << std::endl;
}

出力:

編集: ポイント 4 によると理にかなっていますが、ポイント 2 が実際に有効であるとは言えません。私が知る限り、0 + 0 は 0 に評価され、0 の型はintであるため、それが宣言された型です。

于 2011-05-08T00:48:04.923 に答える