1. ホーム
  2. c++

[解決済み] 値の初期化を試みたが、関数宣言と解釈された。A a(()); で解決しないのはなぜか?

2022-04-26 20:20:12

質問

Stack Overflow が教えてくれた多くのことの中に、いわゆる "most vexing parse" と呼ばれる、古典的に次のような行で示されるものがあります。

A a(B()); //declares a function

これは、直感的にはオブジェクトの宣言のように見えますが a 型の A を取得し、一時的に B オブジェクトをコンストラクタのパラメータとして指定するもので、実際には関数の宣言です。 a を返す A を返す関数へのポインタを取る。 B であり、それ自身はパラメータを取らない。同様に

A a(); //declares a function

も同じカテゴリーに属しますが、これはオブジェクトの代わりに関数を宣言しているからです。さて、最初のケースでは、この問題を回避するために、通常は B() コンパイラはこれをオブジェクトの宣言として解釈します。

A a((B())); //declares an object

しかし、2番目のケースでは、同じようにすると、コンパイルエラーになります

A a(()); //compile error

質問ですが、なぜですか?そうです、正しい「回避策」はこれを A a; しかし、私は、この余分な () は、最初の例ではコンパイラのために働いていましたが、2番目の例でそれを再適用すると、働かなくなります。この A a((B())); を回避する方法は、標準に書かれている特定の例外なのでしょうか?

解決方法は?

C++言語で有効な構文として定義されていないだけなので、賢明な答えはないのですが...。 つまり、言語の定義上、そうなっているのです。

もし、その中に式があるのなら、それは有効です。 例えば

 ((0));//compiles

もっと簡単に言うと、なぜなら (x) は有効な C++ 式であるのに対し () はありません。

言語がどのように定義され、コンパイラがどのように動作するかについて詳しく知るには 形式言語理論 またはもっと具体的に 文脈自由文法(Context Free Grammars、CFG) と有限状態機械などの関連資料があります。 もし興味があるなら、wikipediaのページだけでは不十分で、本を買わなければならないでしょう。