dom*_*nos 8 c++ most-vexing-parse
我有一个构造函数的问题,它没有像我期望的那样工作.
如果我尝试像这样初始化我的类,它将工作,我得到一个可用的对象:
vector<float> v;
MyClass<2> a(v);
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试构建类似下面的类(应该是等效的),结果是非常意外的.编译或运行程序时没有错误消息/警告.但是如果你尝试在某处使用这个变量并调用它的方法(例如a.doSomething()),它就会崩溃.
我在构造函数中放了一些代码来通知我它是否被使用.事实证明,在这种情况下,构造函数中没有实际执行的代码.
MyClass<2> a(vector<float>());
Run Code Online (Sandbox Code Playgroud)
所以我想知道为什么会这样?第二次申报是非法的吗?
编辑:我将发布一些类的代码
template <int x>
class MyClass {
public:
vector<float> v;
MyClass<x>(vector<float> v1) {
v = v1;
}
};
Run Code Online (Sandbox Code Playgroud)
Jam*_*lis 19
MyClass<2> a(vector<float>());
Run Code Online (Sandbox Code Playgroud)
这不是变量声明.它是一个名为函数的声明,a它返回一个MyClass<2>对象,并将一个"指向一个不带参数的函数的指针并作为参数" vector<float>.混乱?是.这就是所谓的"最令人烦恼的解析".
你需要额外的括号:
MyClass<2> a((vector<float>()));
^ ^
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用复制初始化:
MyClass<2> a = MyClass<2>(vector<float>());
Run Code Online (Sandbox Code Playgroud)
或者,由于您的构造函数不是explicit,您可以使用:
MyClass<2> a = vector<float>();
Run Code Online (Sandbox Code Playgroud)
(但是,除非你的意思是vector<float>对象可以隐式转换为MyClass<N>对象,否则你可能想要构造这个构造函数explicit.)
一个好的编译器应该警告你这类事情.Visual C++警告:
警告C4930:'
MyClass<x> a(std::vector<_Ty> (__cdecl *)(void))':未调用prototyped函数(是一个变量定义?)
Clang警告说:
警告:括号被消除歧义为函数声明符
Run Code Online (Sandbox Code Playgroud)MyClass<2> a(vector<float>()); ^~~~~~~~~~~~~~~~~