I saw a blog post which used non-type variadic templates (currently not supported by gcc, only by clang).
template <class T, size_t... Dimensions> struct MultiDimArray { /* ... */ };
The example in the post compiles fine but I failed to get it to work with function templates.
Can anyone help figuring out the correct syntax (if such exists)?
int max(int n) { return n; } // end condition template <int... N> // replacing int... with typename... works int max(int n, N... rest) // !! error: unknown type name 'N' { int tmp = max(rest...); return n < tmp? tmp : n; } #include <iostream> int main() { std::cout << max(3, 1, 4, 2, 5, 0) << std::endl; }
A template non-type parameter is a template parameter where the type of the parameter is predefined and is substituted for a constexpr value passed in as an argument. A non-type parameter can be any of the following types: An integral type. An enumeration type.
Variadic templates are class or function templates, that can take any variable(zero or more) number of arguments. In C++, templates can have a fixed number of parameters only that have to be specified at the time of declaration.
Variadic functions are functions that can take a variable number of arguments. In C programming, a variadic function adds flexibility to the program. It takes one fixed argument and then any number of arguments can be passed.
For example, given a specialization Stack<int>, “int” is a template argument. Instantiation: This is when the compiler generates a regular class, method, or function by substituting each of the template's parameters with a concrete type.
You are simply confusing type names and non-type names. What you want simply doesn’t work.
You can probably use variadic non-type templates in functions, but not as (non-template) arguments:
template <int N, int... Rest> int max() { int tmp = max<Rest...>(); return N < tmp ? tmp : N; }
std::cout << max<3, 1, 4, 2, 5, 0>() << std::endl;
… although I haven’t tested this and I’m not sure how this should work given that you need to have a partial specialisation as the base case. You could solve this by dispatching to a partially specialised struct:
template <int N, int... Rest> struct max_t { static int const value = max_t<Rest...>::value > N ? max_t<Rest...>::value : N; }; template <int N> struct max_t<N> { static int const value = N; }; template <int... NS> int max() { return max_t<NS...>::value; }
This will work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With