шаблоны — Почему это утверждение не вызывает конструкторы

Шаблонный класс и обычный класс:

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());, это работает хорошо. Итак, здесь есть несколько случаев:

  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.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

3

Решение

Заявление Holder<Animal> a(Animal()); не создает переменную, но объявляет функцию, которая возвращает Holder<Animal> и это принимает функцию в параметре. Обычно это называется самый неприятный разбор, из-за этой неоднозначности (что можно ожидать переменную, а не объявление функции).

Херб Саттер объясняет различные возможные синтаксисы Вот. В C ++ 11 возможное решение:

auto a = Holder<Animal> {};
7

Другие решения

Вы жертва «самого неприятного разбора»:

Holder<Animal> a(Animal()); анализируется как функция с именем a, который возвращает Holder<Animal> и принимает в качестве параметра другую функцию, которая не имеет параметров и возвращает Animal,

В C ++ 11 вы можете решить эту проблему с помощью равномерной инициализации:

Holder<Animal> a{Animal{}};

3

По вопросам рекламы [email protected]