Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the point of unnamed non-type template parameters?

According to the reference, the name of a non-type template parameter is optional, even when assigning a default value (see (1) and (2)). Therefore these template structs are valid:

template <int> struct Foo {};
template <unsigned long = 42> struct Bar {};

I haven't seen a possibility of accessing the values of the non-type parameters. My question is: What's the point of unnamed/anonymous non-type template parameters? Why are the names optional?

like image 441
andreee Avatar asked Jan 20 '20 14:01

andreee


People also ask

What is non-type template parameters?

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. A pointer or reference to a class object.

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 can be passed by non-type template parameters during?

What can be passed by non-type template parameters during compile time? Explanation: Non-type template parameters provide the ability to pass a constant expression at compile time. The constant expression may also be an address of a function, object or static class member.

Can we use non-type parameters as argument templates?

A non-type template argument provided within a template argument list is an expression whose value can be determined at compile time. Such arguments must be constant expressions, addresses of functions or objects with external linkage, or addresses of static class members.


2 Answers

First, we can split declaration from definition. So name in declaration is not really helpful. and name might be used in definition

template <int> struct Foo;
template <unsigned long = 42> struct Bar;

template <int N> struct Foo {/*..*/};
template <unsigned long N> struct Bar {/*..*/};

Specialization is a special case of definition.

Then name can be unused, so we might omit it:

template <std::size_t, typename T>
using always_t = T;

template <std::size_t ... Is, typename T>
struct MyArray<std::index_sequence<Is...>, T>
{
    MyArray(always_t<Is, const T&>... v) : /*..*/
};

or used for SFINAE

template <typename T, std::size_t = T::size()>
struct some_sized_type;
like image 184
Jarod42 Avatar answered Oct 27 '22 00:10

Jarod42


What's the point of unnamed/anonymous non-type template parameters?

I can think of specialization:

template<int = 42>
struct Foo{
   char x;
};

template<>
struct Foo<0> {
   int x;
};

template<>
struct Foo<1> {
   long x;
};

Then:

Foo<0> a; // x data member is int
Foo<1> b; // x data member is long
Foo<7> c; // x data member is char
Foo<>  d; // x data member is char
like image 44
ネロク・ゴ Avatar answered Oct 26 '22 22:10

ネロク・ゴ