Шаблон функции-члена с количеством параметров, зависящим от интегрального параметра шаблона

У меня есть следующий шаблон класса:

template<class T, unsigned N>
class MyClass;

где T - некоторый тип, N - количество компонентов. Можно инициализировать класс с помощью MyClass {a1, a2, a3} , где количество аргументов равно N .

Я хочу добавить шаблон функции-члена (назовем его foo ) из MyClass , который отвечал бы следующим требованиям:

  1. Это шаблон другого типа T2 (т.е. template void foo (..) )
  2. Он принимает достаточно данных для создания MyClass , но не менее и не более. Нарушение этого приводит к ошибке времени компиляции.
  3. Он выводит 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
...
12
задан p12 1 February 2012 в 17:57
поделиться