我想知道在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 (*)())’
谢谢!
答案 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
的匿名实例。