Почему мы должны указать & lt; & gt; для шаблона класса с параметрами по умолчанию?

Я нахожу что-то раздражающее в C ++, и я не знаю, есть ли хитрость, чтобы избежать этого без лишних затрат. Проблема заключается в следующем:

Для функции шаблона мы можем иметь:

// Function declaration/definition
template<bool Option = false> void myFunction()
{
std::cout<<"Option = "<<Option<<std::endl;
}

// Then I can use :
myFunction<false>();
myFunction<true>();
myFunction(); // <- NO PROBLEM HERE

Теперь для шаблона класса:

// Class definition/declaration
template<bool Option = false> class MyClass
{
};

// Then I can use :
myClass<false> x;
myClass<true> y;
myClass z; // <- PROBLEM HERE : only "MyClass<> z;" will compile !

Почему причина такого поведения?
Есть ли хитрость, чтобы избежать этого?
Для класса с необязательными параметрами, передаваемыми в качестве шаблона, я считаю, что это не удобно для конечного пользователя: он должен иметь возможность использовать реализацию по умолчанию в качестве класса без шаблонов …

7

Решение

Почему причина такого поведения?

Это потому, что функции могут быть перегружены, а типы — нет.

Когда вы пишете вызов функции, компилятор заполняет набор перегрузок всех функций, которые он может найти с этим именем, и затем выясняет, какие из них соответствуют переданному аргументу (ам). Теперь, чтобы это работало чисто с шаблонами функций, это позволяет типам аргументов шаблона быть выведенными из параметров. Поскольку вывод параметров типа в общем случае разрешен, он работает для вашего случая, даже если вместо него задан параметр по умолчанию.

Типы, однако, не перегружены. В то время как myFunction<true>() а также myFunction<false>() оба связаны с тем, насколько они будут участвовать в одном наборе перегрузки, myClass<true> а также myClass<false> отделены и несвязанный типы. Без эквивалента перегрузки имен типов, нет мотивации для добавления особого случая для неявного именования полностью специализированного шаблонного класса. Параметры никогда не могут быть выведены, так что это будет специальный синтаксис только для случая, когда все они по умолчанию.

Есть ли хитрость, чтобы избежать этого?

В общем, если вы хотите получить вывод аргумента шаблона для шаблонных классов, вы можете предоставить оболочку функции шаблона (лучше всего работает с C ++ 11 auto)

template <bool Option=false> class MyClass {};
template <bool Option=false> MyClass<Option> make_my_class() {
return MyClass<Option>();
}
// ...
auto z = make_my_class();

В противном случае, я думаю, используя typedef (согласно комментарию Реми) — лучший вариант.

8

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

myClass это шаблон класса, а не класс. Только myClass<true>, или же myClass<>, это класс.

Так же, myFunction это шаблон функции, а не функция. Тем не менее, когда вы ссылающееся шаблонная функция, аргументы шаблона могут быть выведены для вас, и вы не нужно явно указать аргументы шаблона, если они могут быть выведены. Таким образом, выражение вызова функции myFunction(); действителен, и первый аргумент выводится как false, Просто вывод происходит благодаря аргументу по умолчанию, а не к аргументам функции.

3

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector