次のコード例はコンパイルされます。
#define USE_RVALUE // line 1
template<class data_type>
class Container
{
data_type& data;
public:
#ifdef USE_RVALUE
Container(data_type&& _data) : data(_data) {}
#endif
Container(data_type& _data) : data(_data) {}
};
int main()
{
double d = 42.0;
Container<double> c1(d);
Container<double> c2(1.0f); // line 18
return 0;
}
私のコンパイラコマンド:
g++ -std=c++11 -Wall ref.cpp -o ref # g++ is 4.7.1
行 1 をアウトコメントすると、g++ は次のように文句を言います。
no matching function for call to ‘Container<double>::Container(float)’
ref.cpp:18:34: note: candidates are:
ref.cpp:11:9: note: Container<data_type>::Container(data_type&) [with data_type = double]
ref.cpp:11:9: note: no known conversion for argument 1 from ‘float’ to ‘double&’
[... (more candidates)]
もちろん、エラーは明確で、C++03 の典型的なエラーです: これらの右辺値が const でない場合、右辺値からの参照は許可されません。しかし、なぜ右辺値コンストラクター (つまり、#ifdef
有効化) で機能するのでしょうか? 初期化子リストにも同じ状況があります: 非 const 値からの参照。
また、説明すると・・・このコードは「良いコーディングスタイル」なのか「避けるべき」なのか?