Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Non-type variadic function templates in C++11

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;    } 
like image 716
Motti Avatar asked Oct 24 '11 14:10

Motti


People also ask

What are non-type parameters for templates?

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.

What is a Variadic template C++?

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.

What is variadic function in C?

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.

Which is correct example of template parameters?

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.


1 Answers

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.

like image 88
Konrad Rudolph Avatar answered Oct 03 '22 23:10

Konrad Rudolph