web-dev-qa-db-ja.com

引数のないコンストラクターに括弧がないのは言語標準ですか?

私はg ++を使用してCygwinでC++プログラムをコンパイルしていましたが、コンストラクターに引数がないクラスがありました。私は行を持っていました:

MyClass myObj();
myObj.function1();

そしてそれをコンパイルしようとすると、私はメッセージを受け取りました:

error: request for member 'function1' in 'myObj', which is of non-class type 'MyClass ()()'

少し調べたところ、最初の行を

MyClass myObj;

以前にC++でかっこを使用して空のコンストラクター宣言をしたことがあると断言できます。これはおそらく私が使用しているコンパイラーの制限ですか、それとも言語標準では、引数のないコンストラクターには括弧を使用しないと本当に言われていますか?

51
mring

MyClass myObj();は、空のイニシャライザまたは関数宣言を持つオブジェクト定義として解析できますが、言語標準では、あいまいさが常に解決されて関数宣言が優先されるように指定されています。空の括弧イニシャライザは、他のコンテキストで許可されています。 new式の中、またはvalue-initializedを一時的に作成します。

54
CB Bailey

これは最も厄介な解析問題と呼ばれます。パーサーが見たとき

MyClass myObj();

パラメータを持たず、myObjを返すMyClassという関数を宣言していると考えられます。

それを回避するには、以下を使用します。

MyClass myObj;
52
Peter Alexander

私はこれをC++標準(8.5.8)で見つけました:

イニシャライザが空の括弧のセット、つまり()であるオブジェクトは、値で初期化されます。

[注:()は初期化子の構文では許可されていないため、

X a ();

はクラスXのオブジェクトの宣言ではなく、引数を取らずXを返す関数の宣言です。形式()は、他の特定の初期化コンテキスト(5.3.4、5.2.3、12.6.2)で許可されています。 —エンドノート]

19
suszterpatt

これはかなりよく知られた問題であり、コンパイラに依存しません。基本的に、実行していることは、MyObj型を返す関数を宣言することでした。当然のことながら、コンストラクタを呼び出すことができませんでした。詳しい説明は C++ faq lite を参照してください

10
Liz Albin

さらに別の最も慎重な解析ヒット。例を参照してください ソート関数はスタック上に作成された関数オブジェクトでは機能しませんか?

4
AProgrammer
_MyClass myObj();
_

これは関数宣言として解析され、関数はmyObjと呼ばれ、引数を取らず、MyClassオブジェクトを返します。コンパイラがそれを受け入れるのを見たことがありません。一方、MyClass* myPtr = new MyClass();は許容範囲内ですが、混乱するかもしれませんか?

4
sbk

この行により、コンパイラーは、引数をとらずmyObjを返すMyClassという名前の関数を宣言していると見なします。このあいまいさの解決は確かに迷惑です。

3
Ari

標準では括弧は必要ありません。

_int* x = new int;
_

正しい構文です。

あなたの場合、myclass myobj();は関数プロトタイプです。一方、_myclass myobj;_は変数です。

1
JonH