1

c++gcc最新バージョン)の奇妙な動作のように思われるものについて、誰かが助けてくれるのではないかと思います。以下は、適切なコンストラクターがないためにコンパイル時エラーが発生すると予想される場合に、正常にコンパイルされるコードです。誰が何が起こっているのか説明できますか?

#include <iostream>
using namespace std;

struct ClassA {
  ClassA() {cout << "hello" << endl;} 
  void speak() {cout << "I am class A" << endl;}
  ~ClassA() {cout << "goodbye" << endl;} 
};

struct ClassB {
    // just an empty struct
};

int main() {
    ClassA myClassA(ClassB()); // trying to construct class A from an rvalue reference to class B is ok?
    return 0;
}

}

の関数を呼び出そうとするとclass A、コンパイル時エラーが発生します。

int main() {
    ClassA myClassA(ClassB());
    myClassA.speak();
    return 0;
}

結果:

error: request for member ‘speak’ in ‘myClassA', which is of non-class type ‘ClassA(ClassB (*)())’

ありがとう!

4

3 に答える 3

3

オブジェクトを宣言することはまったくありません。代わりに、functionを宣言したので、コンストラクターはまったく必要ありません。ClassB()(関数型を示すことに注意してください!)

一時オブジェクトからオブジェクトを構築する場合は、次の構文のいずれかを試してください。

ClassA x1 { ClassB{} };   // C++11 only

ClassA x2((ClassB()));    // parenthesized expression is never a type declaration
于 2013-01-23T22:08:29.063 に答える
1

ClassA myClassA(ClassB());aを返し、aを返し、引数を取らない関数へのポインターである 1 つの引数を取る、呼び出される関数を宣言します。これは最も厄介な parseです。myClassAClassAClassB

于 2013-01-23T22:09:37.487 に答える
1

これは、Most Vexing Parse と呼ばれる状況です。

まず第一に、コンストラクターClassB あります。独自のものを作成しない場合は、コンパイラが提供します。そしてClassB、有効なコピー構造のように見える に のインスタンスを渡した行で、実際には、 のインスタンスを返し、ClassAの匿名インスタンスを取る関数の宣言としてその行が評価されますClassB

于 2013-01-23T22:14:26.917 に答える