次のプログラムを検討してください。
struct X
{
X(int, int) { }
X(X&&) { }
};
int main()
{
X x( {0, 1} ); // Doesn't compile on ICC 13.0.1, compiles on
// Clang 3.2, GCC 4.7.2, and GCC 4.8.0 beta.
}
GCC 4.7.2、GCC 4.8.0、およびClang 3.2でコンパイルすると、このプログラムは次のことを行います(*)。
- 次に、値をコンストラクターに
X
渡す型の一時を構築します。0
1
- 移動-
X
その一時的なものから構築します。
代わりに、ICC 13.0.1では、コンパイルされません。
質問#1:誰が正しいですか?
(*)実際には、一時の作成とmoveコンストラクターの呼び出しは省略されていますが、-fno-elide-constructors
オプションを使用してコンパイルし、コンストラクターにいくつかの印刷出力を追加すると、これが行われていることがわかります。
ここで、上記のプログラムのわずかなバリエーションを考えてみましょう。ここでは、均一な初期化を使用して直接初期化していますx
。
int main()
{
X x{ {0, 1} }; // ERROR! Doesn't compile.
// ^........^
}
括弧の代わりに中括弧を使用してここで何かを変更することは期待していませんが、どういうわけかそうです。このプログラムは、テストしたコンパイラ(Clang 3.2、GCC 4.7.2、GCC 4.8)ではコンパイルされません。 0ベータ、およびICC 13.0.1)。
質問2:なぜですか?