构造函数不返回可用对象

时间:2011-03-19 17:53:20

标签: c++ most-vexing-parse

我的构造函数有问题,但是我没想到这个问题。

如果我尝试像这样初始化我的类,它将起作用并且我得到一个可用的对象:

vector<float> v;
MyClass<2> a(v);

但是,如果我尝试构建类似下面的类(应该是等效的),结果是非常意外的。编译或运行程序时没有错误消息/警告。但是如果你尝试在某个地方使用这个变量并调用它的方法(例如a.doSomething()),它就会崩溃。

我在构造函数中放了一些代码来通知我它是否被使用。事实证明,在这种情况下,构造函数中没有实际执行代码。

MyClass<2> a(vector<float>());

所以我想知道为什么会这样?第二次申报是非法的吗?

编辑:我会发布一些类的代码

template <int x>
class MyClass {
public:
    vector<float> v;
    MyClass<x>(vector<float> v1) {
      v = v1;
    }

};

1 个答案:

答案 0 :(得分:18)

MyClass<2> a(vector<float>());

这不是变量声明。它是一个名为a的函数的声明,它返回一个MyClass<2>对象,并将一个“指向不带参数的函数的指针作为参数,并返回vector<float>”。混乱?是。这就是所谓的“最令人烦恼的解析”。

您需要额外的括号:

MyClass<2> a((vector<float>()));
             ^               ^

或者,您可以使用复制初始化:

MyClass<2> a = MyClass<2>(vector<float>());

或者,由于您的构造函数不是explicit,您可以使用:

MyClass<2> a = vector<float>();

(但是,除非你的意思是vector<float>个对象可以隐式转换为MyClass<N>个对象,否则你可能想要构建这个构造函数explicit。)


一个好的编译器应该警告你这类事情。 Visual C ++警告:

  

警告C4930:'MyClass<x> a(std::vector<_Ty> (__cdecl *)(void))':未调用prototyped函数(是否为变量定义?)

Clang警告说:

  

警告:括号被解除歧义为函数声明符

MyClass<2> a(vector<float>());
            ^~~~~~~~~~~~~~~~~