C ++构造函数问题

时间:2013-01-23 22:07:31

标签: c++ constructor rvalue most-vexing-parse

我想知道在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 (*)())’

谢谢!

3 个答案:

答案 0 :(得分:3)

你永远不会宣布一个对象。相反,你已经声明了一个函数,因此根本不需要构造函数。 (注意ClassB()表示函数类型!)

如果要从临时构造对象,请尝试以下语法之一:

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

ClassA x2((ClassB()));    // parenthesized expression is never a type declaration

答案 1 :(得分:1)

ClassA myClassA(ClassB());声明一个名为myClassA函数,它返回ClassA并接受一个参数,该参数是一个返回{{1}的函数的指针并且没有参数。这是most vexing parse

答案 2 :(得分:1)

这种情况称为最令人烦恼的解析。

首先和formost,ClassB 确实有一个构造函数。当您不创建自己的编译器时,编译器会为您提供一个。在您将ClassB实例传递给看似有效的复制结构的行上,实际发生的是该行被评估为返回ClassA实例的函数的声明,采用ClassB的匿名实例。