У меня есть следующий шаблон класса:
template<class T, unsigned N>
class MyClass;
где T
- некоторый тип, N
- количество компонентов. Можно инициализировать класс с помощью MyClass {a1, a2, a3}
, где количество аргументов равно N
.
Я хочу добавить шаблон функции-члена (назовем его foo
) из MyClass
, который отвечал бы следующим требованиям:
T2
(т.е. template void foo (..)
) MyClass
, но не менее и не более. Нарушение этого приводит к ошибке времени компиляции. T2
из типов параметров. Т.е. Я хочу, чтобы можно было вызвать foo ({a1, a2, a3})
или foo (a1, a2, a3)
или аналогичный, без ввода
или MyClass
каждый раз.Есть ли способ реализовать функцию так, чтобы выполнялись вышеуказанные требования?
Я уже думал и / или пробовал следующие решения:
1) Очевидное:
...
template<class T2>
void foo(MyClass<T2, N> arg);
...
a.foo({1,2,3}); //compile-time error
Не может работать в принципе, потому что списки инициализаторов в фигурных скобках - это невыведенный контекст, поэтому они не могут выводить какие-либо типы. Это весьма прискорбно, я был бы очень рад, если бы это сработало.
2) initializer_list
Не может работать в принципе, потому что не может проверить количество аргументов во время компиляции.
3) Магия вариативного шаблона
Что-то вроде функции ниже было бы здорово:
template<class...T2, class std::enable_if<sizeof...(T2) == N, int>::type = 0>
void foo(T2... args);
..
foo(1,2,3);
Однако мне не удалось заставить ее работать - T2 все еще не мог быть выведен. Может кто знает почему? Я использовал снимок GCC4.7 20120121.
4) Уродливый
По сути, это то же самое, что и выше, только расширено до нескольких перегрузок для разных N. Я бы лучше переопределил MyClass
как набор специализаций для другое N
s, чем использовать этот.
template<class T2, class std::enable_if<N == 1, int>::type = 0>
void fun(T2 a1); //if N == 1
template<class T2, ..>
void fun(T2 a1, T2 a2); //if N == 2
template<class T2, ..>
void fun(T2 a1, T2 a2, T2 a3); //if N == 3
...