I have the following class template:
template
class MyClass;
where T
is some type, N
- num
Your third variant's second non-type param should have prefix typename
not class
:
template<class...T2, typename std::enable_if<sizeof...(T2) == N, int>::type = 0>
void foo(T2... args);
..
foo(1,2,3);
Check it
Gcc 4.7.0 snapshots has some bugs with templates I guess, if you try it with gcc 4.6.2/1 it shall work.
Why not use a static_assert
?
template <typename T, size_t N>
class MyClass
{
public:
template <typename... Args>
void foo(Args&&... args)
{
static_assert(sizeof...(Args) == N, "Wrong number of arguments.");
// Rest of the implementation.
}
};
Maybe like this:
#include <utility>
#include <type_traits>
template <typename T, unsigned int N>
class MyClass
{
template <typename ...Args>
typename std::enable_if<std::is_constructible<MyClass<T, N>, Args...>::value>::type
foo(Args &&... args)
{
// for example:
MyClass<T, N> m(std::forward<Args>(args)...);
// ...
}
};
This will work only if MyClass
has a constructor that accepts the relevant arguments directly (like MyClass(A1, A2, A3)
), but I don't think it works if MyClass
has a constructor that requires an initializer list, nor will it work if MyClass
is an aggregate that requires brace-initialization.
That said, it doesn't look like your MyClass
could possibly accept an initializer list, since you said that it has to take precisely N
arguments, which an IL cannot promise.
May be, based on your 3rd variant, you can extract first argument from initializer list and deduce type by it
template<class U, class...T2, class std::enable_if<sizeof...(T2) == N-1, int>::type = 0>
void foo(U u, T2... args)
{
MyClass<U, N>({u, args...});
}