I have the following class template:
template<class T, unsigned N>
class MyClass;
where T is some type, N - number of components. It is possible to initialize the class using MyClass{a1, a2, a3} where the number of arguments is equal to N.
I want to add a member function template (let's name it foo) of MyClass that would meet the following requirements:
- It is templated by another type
T2(i.e.template<class T2> void foo(..)) - It accepts enough data to construct
MyClass<T,N>, but not less and not more. Violating this results in a compile-time error. - It deduces
T2from the types of the parameters. I.e. I want that it would be possible to callfoo({a1, a2, a3})orfoo(a1, a2, a3)or similar, without typing<double>orMyClass<double,N>every time.
Is there a way to implement the function so that the above requirements are satisfied?
I've already thought about and/or tried the following solutions:
1) The obvious one:
...
template<class T2>
void foo(MyClass<T2, N> arg);
...
a.foo({1,2,3}); //compile-time error
Can't work in principle, because braced initializer lists are a non-deduced context, thus they can't deduce any types. That's quite unfortunate, I'd be very happy if this worked.
2) initializer_list
Can't work in principle, because it can't check the number of arguments at compile-time.
3) Variadic template magic
Something like the function below would be neat:
template<class...T2, class std::enable_if<sizeof...(T2) == N, int>::type = 0>
void foo(T2... args);
..
foo(1,2,3);
However, I couldn't get it to work - T2 still couldn't be deduced. Maybe someone knows why? I used GCC4.7 20120121 snapshot.
4) The ugly one
Essentially this is the same as the above one, just expanded into several overloads for different N. I would better reimplement MyClass as a set of specializations for different Ns than to use this one.
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
...