Вывод параметра шаблона из аргументов работает только для функций , никогда для классов . Пока вы не знаете тип класса, то есть все его параметры шаблона, вы даже не знаете, какие функции-члены имеет класс!
Итак, вы всегда должны произносить параметры шаблона, если хотите построить объект напрямую:
a<int> x(30);
Вот небольшой мысленный эксперимент, который расширит вышесказанное. Предположим, у нас есть
template <typename T> class Foo;
и мы звоним Foo::somefunction(x);
, где x
- некоторый тип. Вы думаете, ну, я объявил somefunction()
так:
template <typename T> class Foo
{
static void somefunction(const T & x);
};
, поэтому должно быть очевидно, что T
того же типа, что и тип x
. Но теперь представьте, что у меня есть специализация:
template <> class Foo<char>
{
static void anotherfunction(double x);
};
Класс Foo<char>
даже не имеет функцию somefunction()
, поэтому выражение Foo::somefunction(x)
даже не доходит до той стадии, когда я мог бы найти аргумент!
Обычным способом решения этой проблемы является создание бесплатной вспомогательной функции, которая создает ваш объект:
template <typename T> a<T> make_a(const T & x) { return a<T>(x); }
Поскольку это шаблон function , его параметры могут быть выведены:
make_a(30); // type a<int>
make_a("hello"); // type a<char[6]>