別のばかげた litb 投稿の必要性を感じました。
string str1 = "foo";
これはcopy-initializationと呼ばれます。これは、一時変数を省略しない場合、コンパイラが行うことは次のとおりであるためです。
string str1(string("foo"));
使用される変換コンストラクターが暗黙的であることを確認することに加えて。実際、すべての暗黙的な変換は、コピーの初期化に関して標準で定義されています。型 U から型 T への暗黙的な変換が有効であると言われます。
T t = u; // u of type U
有効です。
対照的に、
string str1("foo");
書かれていることを正確に実行しており、直接初期化と呼ばれます。また、明示的なコンストラクターでも機能します。
ところで、-fno-elide-constructors を使用して、一時変数の省略を無効にすることができます。
-fno-elide-constructors
The C++ standard allows an implementation to omit creating a temporary which
is only used to initialize another object of the same type. Specifying this
option disables that optimization, and forces G++ to call the copy constructor
in all cases.
規格では、実質的に違いはないと述べています
T a = u;
と
T a(u);
T と u の型がプリミティブ型の場合。したがって、両方の形式を使用できます。人々が 2 番目の形式よりも 1 番目の形式を使用するようになるのは、そのスタイルだと思います。
一部の人々は、宣言のあいまいさを解消したいため、状況によっては最初のものを使用する場合があります。
T u(v(a));
と呼ばれるコンストラクターのパラメーターを取得するu
一時的な型を使用して初期化される変数の定義として誰かに見えるかもしれません。しかし実際には、コンパイラがそれに対して行うことは次のとおりです。v
a
T u(v a);
type の引数を取り、v
というパラメータを持つ関数宣言を作成しますa
。だから人々はそうする
T u = v(a);
たとえ彼らができたとしても、それを明確にするために
T u((v(a)));
また、関数パラメータの周りに括弧がないため、コンパイラはそれを関数宣言ではなく変数定義としても読み取ります:)