0

重複の可能性:
括弧の空のセットを使用して引数なしでコンストラクターを呼び出すとエラーになるのはなぜですか?
最も厄介な解析: なぜ A は a(()); を実行しないのですか? 仕事?

これは私を怒らせます。単純すぎるのかもしれません。

struct Foo
{
  Foo() {}
  Foo(const Foo& f) {}
  void work() {}
};

int main()
{
  Foo f( Foo() );
  f.work();
}

GCC 4.6 は私に与えます:

error: request for member ‘work’ in ‘f’, which is of non-class type ‘Foo(Foo (*)())’

コピー操作を省略した後、有効なコードは次のようになります。

int main()
{
  Foo f;
  f.work();
}

でもなんで電話できないのwork()??

編集:

はい、複製します (以下を参照)。最初に検索したときに元の投稿が見つかりませんでした。これは、この症状の原因が予想外の場所にあるためです。

4

4 に答える 4

3

Foo f( Foo() );は関数宣言だからです。

私はあなたが欲しいと思います:Foo f;

または、コピー構築したい場合:

Foo f( (Foo()) );
于 2012-07-26T11:12:55.350 に答える
1

f は実質的に main 関数内の関数宣言です。試す

Foo f((Foo())); // to make the definition of f explicit enough.
于 2012-07-26T11:13:56.317 に答える
1

n3337 8.2

関数スタイルのキャストと 6.8 で言及されている宣言との間の類似性から生じるあいまいさは、宣言のコンテキストでも発生する可能性があります。そのコンテキストでは、パラメーター名を冗長な括弧で囲む関数宣言と、関数スタイルのキャストを初期化子として使用するオブジェクト宣言のどちらかを選択します。6.8 で述べたあいまいさの場合と同様に、解決策は、宣言である可能性のある構成を宣言と見なすことです。[ 注: 宣言は、非関数スタイルのキャスト、初期化を示す = によって、またはパラメーター名の周りの冗長な括弧を削除することによって、明示的に曖昧さをなくすことができます。— 終わりの注記] [例:

struct S {
S(int);
};
void foo(double a) {
S w(int(a));
//function declaration
S x(int());
//function declaration
S y((int)a);
//object declaration
S z = int(a);
//object declaration
}

— 終了例 ]

于 2012-07-26T11:17:21.210 に答える
1

C++ パーサーはFoo f(Foo());、expression を署名付きの関数宣言として解釈しますFoo(Foo(*)())。つまり、関数は Foo を返し、Foo を返す関数への関数ポインターを取ります。このように引数の周りに明示的な括弧を追加Foo f((Foo()));すると、あいまいさが解決されます。Foo f;しかし、冗長なコードを避けるために実際に行うことを検討してください。

于 2012-07-26T11:18:00.607 に答える