Рассмотрим следующие struct
s:Использование нетиповых аргумент шаблона при частичной специализации
//Implementations provided elsewhere
struct A { A(int i, double d, std::string s); /* ... */ };
struct B { B(double d1, double d2); /* ... */ };
У меня есть два класса преобразования которых шаблон подписи выглядит следующим образом:
TupleAs< A, int, double, std::string > via1 { ... };
ArrayAs< B, double, 2 > via2 { ... };
Предсказуемо, TupleAs
преобразует триплет int
, double
и std::string
значения в объект типа A
. Аналогично, ArrayAs
преобразует пару из двух значений double
в объект типа B
. (И да, есть причины, почему я не могу назвать в A
и B
конструкторов непосредственно.)
Улучшение синтаксиса
Я хотел бы изменить синтаксис, так что я могу сделать следующее:
TupleAs< A(int,double,std::string) > via1 { ... };
ArrayAs< B(double,2) > via2 { ... };
который, я думаю, более подробно описывает процесс преобразования. TupleAs
шаблон декларации и соответствующей частичной специализации будет выглядеть следующим образом:
template <typename T> struct TupleAs;
template <typename T, typename ... Args>
struct TupleAs<T(Args...)> { ... };
ошибки компилятора
Однако, если я пытаюсь сделать что-то подобное с версией ArrayAs
:
template <typename T> struct ArrayAs;
template <typename T, typename U, unsigned N>
struct ArrayAs<T(U,N)> { ... };
I получить следующие ошибки в clang (3.6) при попытке его создания (ArrayAs< B(double,2)> test;
):
typeAs.cpp:14:22: error: unknown type name 'N'
struct ArrayAs<T(U,N)>{
^
typeAs.cpp:14:10: warning: class template partial specialization contains a template parameter that cannot be deduced; this partial specialization will never be used
struct ArrayAs<T(U,N)>{
^~~~~~~~~~~~~~~
typeAs.cpp:13:45: note: non-deducible template parameter 'N'
template<typename T, typename U, unsigned N>
^
Диагностика ошибок gcc немного отличается, но я не буду публиковать ее здесь.
Я признаю, что мои навыки шаблонирования должны быть лучше, чем они есть, и я также признаю, что аналогичная декларация std::function<B(double,2)>
явно абсурдна. Но может ли кто-нибудь сказать мне, почему конкретный синтаксис, который я пытаюсь достичь, не разрешен? Я просмотрел стандарт C++ 14 и не смог найти соответствующую часть, и у меня возникли проблемы с интерпретацией диагностического сообщения clang.
Вы специализируетесь на выборе типа функции. Тип функции имеет вид 'type (types ...)', нет места для целого числа. С другой стороны, синтаксис 'B (double, 2)' не имеет смысла в C++ в любом контексте. Сообщение об ошибке может, по общему признанию, иметь больше смысла. – Quentin
Вам нужно, чтобы '2' был параметром времени компиляции? – sfjac