それは単に好みですか、それとも特定のインスタンスが必要な場合がありますか? 初期化のために次のバリアントを参照しています
T t(e); // direct initialization
T t = e; // copy initialization
それは単に好みですか、それとも特定のインスタンスが必要な場合がありますか? 初期化のために次のバリアントを参照しています
T t(e); // direct initialization
T t = e; // copy initialization
あなたが説明するものの実際の名前は、暗黙的および明示的な代入ではありませんが、次のとおりです。
T x = a;
T x(a);
それらは同等ではありません。特に、変換が必要なコンテキストでは、たとえばT
がクラス型でa
あり、別の型である場合です (変換を含まないコンテキストの例については、Alf コメントを参照してください)。次のコードを検討してください。
class Test
{
public:
explicit Test(int i) { /* ... */ }
};
int main()
{
Test t(0); // OK : calls Test::Test(int)
Test u = 0; // KO : constructor is marked explicit
}
標準 (8.5/14) を言い換えると:
main
私の例の 2 行目のように、他のコピー初期化のケースでは、ユーザー定義の変換シーケンスが考慮されます。Test
暗黙的な変換のためのコンストラクターの使用がexplicit
キーワードによって許可されていないため、2 行目はコンパイルに失敗します。のような直接初期化
std::istringstream stream( "blah blah" );
問題の型(ここstd::istringstream
ではC ++標準ライブラリから)にアクセス可能なコピーコンストラクタがない場合に必要です。
のようなコピーの初期化
std::istringstream stream = "blah blah"; //! NOT VALID
の右側に一時オブジェクトが作成されたかのように実行され、=
宣言されている変数を初期化するためにその一時オブジェクトが使用されるかのように実行されるため、アクセス可能なコピーコンストラクタが必要です。
逆に、C ++ 98では、中括弧の初期化子を使用するためにコピー初期化構文が必要です。たとえば、直接初期化を使用して集計を初期化することはできません。ただし、中括弧の初期化子でコピーの初期化を使用できます。
#include <string>
using namespace std;
struct Answer
{
int nVotes;
string description;
};
int main()
{
Answer const incorrect = { 26, "they're the same!" };
Answer const correct = { -1, "nah, they're different, actually" };
}
したがって、大きな違いがあります。
私は一般的に、明快さのためにコピー初期化構文を好みます。ただし、上記のように、残念ながら直接初期化が必要な場合があります。C++の教科書の著者であるFrancisGlassborowなどの一部の人々は、代わりに、優先する初期化構文として直接初期化を採用しています(理由はわかりませんが、私の目にはあまり明確ではなく、「最も厄介な解析」の問題が発生します)。場合によってはコピーの初期化が必要ですが、それは残念なことです。
乾杯&hth。、