模板类和普通类:
template <typename Type>
class Holder
{
public:
Holder(const Type& value) : held_(value)
{
cout << "Holder(const Type& value)" << endl;
}
Type& Ref() { return held_; }
private:
Type held_;
};
class Animal
{
public:
Animal(const Animal& rhs) { cout << "Animal(const Animal& rhs)" << endl; }
Animal() { cout << "Animal()" << endl; }
~Animal() { cout << "~Animal" << endl; }
void Print() const { cout << "Animal::Print()" << endl; }
};
然后我想使用此语句Holder<Animal>
实例化Holder<Animal> a(Animal());
,但是它失败了。我的意思是Animal()
不被视为临时对象。并且此语句不会调用Holder
的构造函数。
如果有人可以解释?我不清楚。我猜这里有a
成为一种类型。然后,我使用Holder<Animal> a = Holder<Animal>(Animal());
,它运作良好。所以,这里有一些案例:
Holder<Animal> a(Animal()); a.Ref().Print(); // error
Holder<Animal> a = Holder<Animal>(Animal()); a.Ref().Print(); // ok
Holder<int> b(4); b.Ref() = 10; cout << b.Ref() << endl; //ok
可以解释一下吗?我只是对第一个声明感到困惑。以及此语句导致的错误信息:
GCC4.7.2
:error: request for member 'Ref' in 'a', which is of non-class type 'Holder<Animal>(Animal (*)())'
VS10
:error C2228: left of '.Ref' must have class/struct/union
,error C2228: left of '.Print' must have class/struct/union
答案 0 :(得分:7)
语句Holder<Animal> a(Animal());
不会创建变量,但会声明一个函数,该函数返回Holder<Animal>
并在参数中接受一个函数。它通常被称为most vexing parse,因为这种歧义(人们会期望变量而不是函数声明)。
Herb Sutter解释了不同的可能语法here。在C ++ 11中,可能的解决方案是:
auto a = Holder<Animal> {};
答案 1 :(得分:3)
你是“最令人烦恼的解析”的受害者:
Holder<Animal> a(Animal());
被解析为名为a
的函数,它返回Holder<Animal>
并将另一个函数作为参数,该函数没有参数并返回Animal
。< / p>
在C ++ 11中,您可以使用统一初始化来解决该问题:
Holder<Animal> a{Animal{}};