Home > Net >  Why is using a template as a non-type template parameter allowed?
Why is using a template as a non-type template parameter allowed?

Time:12-30

I discovered that using a template as the »type« of a non-type template parameter seems to be allowed since C 20:

template< typename T >
struct LiteralType {
    T a, b, c;
};

template< LiteralType t >
struct S {
    static constexpr auto value = t;
};

auto f() {
    return S< LiteralType< int >{} >::value;
}

(see https://godbolt.org/z/KdTcY8rqo). Why exactly is this allowed?

Informally, every instantiation of LiteralType is literal (or structural?) type, but where is this formally allowed in the standard?

Reading https://eel.is/c draft/temp.param#6 briefly, only types are allowed for non-type template-parameters, not templates.

CodePudding user response:

The paragraph you read says "a placeholder for a deduced class type". This is standard verbiage for allowing class template argument deduction. Since C 17, we can declare variables as follows

std::vector v{1, 2, 3};

The type of v is deduced via CTAD from the initializer, and the template name serves as placeholder.

The C 20 code you show is just a natural extension of this. The non-type template parameter has its type deduced from the argument you provide as initializer (coincidently, even in C 17 we had deduction in this place, via auto placeholder types).

  • Related