3

次のコードを見てみましょう。

class   const_int                                                                                                                                                                                                    
{                                                                                                                                                                                                                    
public:                                                                                                                                                                                                              
  constexpr const_int(int data) : data_(data) {}                                                                                                                                                                     
  constexpr const_int(const const_int &) = default;                                                                                                                                                                  
  constexpr const_int(const_int &&) = default;                                                                                                                                                                       

private:                                                                                                                                                                                                             
  int   data_;                                                                                                                                                                                                       
};

class   test                                                                                                                                                                                                         
{                                                                                                                                                                                                                    
public:                                                                                                                                                                                                              

  constexpr static const const_int      USER = 42;                                                                                                                                                                

  constexpr static const double         NATIVE = 4.2;                                                                                                                                                                
};

// constexpr const const_int test::USER;

void    pass_by_copie(double)                                                                                                                                                                                        
{                                                                                                                                                                                                                    
}

void    pass_by_copie(const_int)                                                                                                                                                                                     
{                                                                                                                                                                                                                    
}

void    pass_by_const_ref(const const_int&)                                                                                                                                                                          
{                                                                                                                                                                                                                    
}

void    pass_by_rvalue_ref(const_int&&)                                                                                                                                                                              
{                                                                                                                                                                                                                    
}

int     main(void)                                                                                                                                                                                                   
{                                                                                                                                                                                                                    

  pass_by_copie(test::NATIVE);                                                                                                                                                                                       

  pass_by_copie(test::USER);                                                                                                                                                                                         

  pass_by_const_ref(test::USER);                                                                                                                                                                                         

  pass_by_rvalue_ref(const_int(test::USER));                                                                                                                                                                         

  return (0);                                                                                                                                                                                                        
}

次の両方の行:

pass_by_copie(test::USER);
pass_by_const_ref(test::USER);

次のエラーが発生しますg++ 4.7

`test::USER'への未定義の参照

のインスタンスがないことを認識していますtest::USER。(行は意図的にコメントされています)


2つの質問があります:

  1. 関数を呼び出すためにtest::USERの明示的なインスタンスが必要ないのに、の明示的なインスタンスが必要なのはなぜですか?test::NATIVEpass_by_copie

  2. コンパイラがで呼び出すときに、同じコピーを自分で暗黙的に作成できない(または望まない)ときにpass_by_rvalue_ref、一時コピーを明示的に作成して呼び出すことができるのはなぜですか?test::USERpass_by_copietest::USER

ありがとうございました

4

2 に答える 2

2

C++11 のセクション 3.2 から:

名前が潜在的に評価される式として表示される変数は、それが定数式に表示されるための要件を満たし、左辺値から右辺値への変換がすぐに適用されるオブジェクトでない限り、odr 使用されます。

すべてのプログラムには、そのプログラムで ODR で使用されるすべての非インライン関数または変数の定義が 1 つだけ含まれている必要があります。

はodrで使用されるため定義が必要でtest::USERあり、左辺値から右辺値への変換がすぐに行われないため、明らかにodrで使用されます。への呼び出しpass_by_copieは、左辺値から右辺値への変換を実行するように見えます。

于 2012-12-07T19:57:21.250 に答える
1

Clang 4.1 で次のエラーが表示されます。

Undefined symbols for architecture x86_64:
  "test::USER", referenced from:
      _main in Untitled-gXrry2.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

ここで起こっていることは、それが使用されtest::NATIVEている値に単純に置き換えることができ4.2、実際にはシンボルを必要としないと想定しています。ただしtest::USER、 はスカラーではなくクラスのインスタンスであるため、すべての参照test::USERが同じオブジェクトを参照するようにシンボルが必要です。これを考えると、実際には明示的なインスタンスが必要です。

于 2012-12-07T19:31:10.837 に答える