Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Advantages of auto in template parameters in C++17

What are the advantages of auto in template parameters that will (possibly) be introduced with C++17?

Is it just a natural extension of auto when I want to instantiate template code?

auto v1 = constant<5>;      // v1 == 5, decltype(v1) is int auto v2 = constant<true>;   // v2 == true, decltype(v2) is bool auto v3 = constant<'a'>;    // v3 == 'a', decltype(v3) is char 

What else do I gain from this language feature?

like image 686
Damian Avatar asked Jun 25 '16 09:06

Damian


People also ask

Why do we use template template parameter?

Why we use :: template-template parameter? Explanation: It is used to adapt a policy into binary ones.

What is auto template?

An auto keyword in a template parameter can be used to indicate a non-type parameter the type of which is deduced at the point of instantiation. It helps to think of this as a more convenient way of writing: template <typename Type, Type value>

Can we pass Nontype parameters to templates?

Template non-type arguments in C++ It is also possible to use non-type arguments (basic/derived data types) i.e., in addition to the type argument T, it can also use other arguments such as strings, function names, constant expressions, and built-in data types.

What is correct for template parameter?

A template argument for a template template parameter is the name of a class template. When the compiler tries to find a template to match the template template argument, it only considers primary class templates. (A primary template is the template that is being specialized.)


2 Answers

The template <auto> feature (P0127R1) was accepted into C++ in the ISO C++ 2016 meeting in Oulu, Finland.

An auto keyword in a template parameter can be used to indicate a non-type parameter the type of which is deduced at the point of instantiation. It helps to think of this as a more convenient way of writing:

template <typename Type, Type value> 

For example,

template <typename Type, Type value> constexpr Type constant = value; constexpr auto const IntConstant42 = constant<int, 42>; 

can now be written as

template <auto value> constexpr auto constant = value; constexpr auto const IntConstant42 = constant<42>; 

where you don't need to explicitly spell out the type any more. P0127R1 also includes some simple but good examples where using template <auto> with variadic template parameters is very handy, for example for implementations of compile-time lists constant values:

template <auto ... vs> struct HeterogenousValueList {}; using MyList1 = HeterogenousValueList<42, 'X', 13u>;  template <auto v0, decltype(v0) ... vs> struct HomogenousValueList {}; using MyList2 = HomogenousValueList<1, 2, 3>; 

In pre-C++1z, while HomogenousValueList could be simply written as

template <typename T, T ... vs> struct Cxx14HomogenousValueList {}; using MyList3 = Cxx14HomogenousValueList<int, 1, 2, 3>; 

writing an equivalent of HeterogenousValueList would not be possible without wrapping the values in some other templates, for example:

template <typename ... ValueTypes> struct Cxx14HeterogenousValueList {}; using MyList4 = Cxx14HeterogenousValueList<constant<int, 42>,                                            constant<char, 'X'> >; 
like image 90
mceo Avatar answered Sep 29 '22 06:09

mceo


Actually, the case of real values in mceo's (original) answer is explicitly not covered as non-type template parameter.

template <auto ... vs> struct HeterogenousValueList {}; using MyList1 = HeterogenousValueList<42, 'X', 1.3f>; 

See the example given in the mentioned proposal: Modify §14.3.2 paragraph 2:

template<auto n> struct B { /* ... */ }; B<5> b1;   // OK: template parameter type is int B<'a'> b2; // OK: template parameter type is char B<2.5> b3; // error: template parameter type cannot be double 

Just stumbled over the same misconception myself a few days ago.

like image 34
m-j-w Avatar answered Sep 29 '22 04:09

m-j-w