丸括弧 (括弧) の空のセットが C++ で既定のコンストラクターを呼び出すのに有効でないという正当な理由はありますか?
MyObject object; // ok - default ctor
MyObject object(blah); // ok
MyObject object(); // error
毎回「()」を自動的に入力するようです。これが許可されない正当な理由はありますか?
丸括弧 (括弧) の空のセットが C++ で既定のコンストラクターを呼び出すのに有効でないという正当な理由はありますか?
MyObject object; // ok - default ctor
MyObject object(blah); // ok
MyObject object(); // error
毎回「()」を自動的に入力するようです。これが許可されない正当な理由はありますか?
最も厄介な解析
これは、「C++の最も厄介な解析」として知られているものに関連しています。基本的に、コンパイラーが関数宣言として解釈できるものはすべて、関数宣言として解釈されます。
同じ問題の別の例:
std::ifstream ifs("file.txt");
std::vector<T> v(std::istream_iterator<T>(ifs), std::istream_iterator<T>());
v
2つのパラメーターを持つ関数の宣言として解釈されます。
回避策は、括弧の別のペアを追加することです。
std::vector<T> v((std::istream_iterator<T>(ifs)), std::istream_iterator<T>());
または、C ++ 11とリスト初期化(均一初期化とも呼ばれます)を使用できる場合:
std::vector<T> v{std::istream_iterator<T>{ifs}, std::istream_iterator<T>{}};
これでは、関数宣言として解釈する方法はありません。
関数の宣言として扱われるため:
int MyFunction(); // clearly a function
MyObject object(); // also a function declaration
関数の宣言にも同じ構文が使用されます。たとえば、object
パラメータをとらずに返す関数です。MyObject
コンパイラは、引数を取らず MyObject インスタンスを返す関数の宣言であると見なすためです。
より冗長な構築方法を使用することもできます。
MyObject object1 = MyObject();
MyObject object2 = MyObject(object1);
C++0x では、次のことも可能ですauto
。
auto object1 = MyObject();
auto object2 = MyObject(object1);
コンパイラは、次のステートメントが
MyObject object();
戻り値の型がMyObjectでパラメーターがないobjectという名前の関数を宣言するコンストラクター呼び出しまたは関数プロトタイプです。
何度も言いますが宣言です。下位互換性のための方法です。C++ の多くの領域の 1 つは、その遺産のために間抜け/一貫性がなく/苦痛/偽物です。