3

一个模板类和一个普通类:

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>用这个语句实例化 a Holder<Animal> a(Animal());,但是它失败了。我的意思Animal()是不被视为临时对象。而且这个语句不调用Holder's 的构造函数。

如果有人可以解释?我不清楚。我猜a这里会变成一种类型。然后,我使用Holder<Animal> a = Holder<Animal>(Animal());,效果很好。所以,这里有一些情况:

  1. Holder<Animal> a(Animal()); a.Ref().Print(); // error
  2. Holder<Animal> a = Holder<Animal>(Animal()); a.Ref().Print(); // ok
  3. Holder<int> b(4); b.Ref() = 10; cout << b.Ref() << endl; //ok

能解释一下吗?我只是对第一个陈述有点困惑。以及此语句导致的错误信息:

GCC4.7.2error: 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

4

2 回答 2

7

该语句Holder<Animal> a(Animal());不创建变量,但声明了一个返回 aHolder<Animal>并在参数中接受函数的函数。它通常被称为最令人烦恼的 parse,因为这种歧义(人们会期望一个变量而不是一个函数声明)。

Herb Sutter 在这里解释了不同的可能语法。在 C++11 中,一个可能的解决方案是:

auto a = Holder<Animal> {};
于 2013-09-03T06:32:28.700 回答
3

您是“最令人烦恼的解析”的受害者:

Holder<Animal> a(Animal());被解析为一个带有 name 的函数a,它返回 aHolder<Animal>并将另一个函数作为参数,该函数没有参数并返回 an Animal

在 C++11 中,您可以通过使用统一初始化来解决该问题:

Holder<Animal> a{Animal{}};

于 2013-09-03T06:34:41.973 回答