15
class Example {

   // ...
};

template <typename T, Example ex>  //Error
class MyExample{

   // ...
};

My question is why can't template non-type parameters be of class type?

The error that I get is

error: ‘class Example’ is not a valid type for a template constant parameter

McGrath
  • 151
  • 1
  • 1
  • 3

3 Answers3

18

Simply, because those are the rules. Rationally, template parameters have to be resolved at compile time and objects of class type are only constructed (even temporaries and those with static storage duration) at run time. You can only have template parameters that are "values" resolvable at compile time such as integers and types. It is possible to have template parameters that are pointers or references to objects, though.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
8

According to c++ standard,

A non-type template-parameter shall have one of the following (optionally cv-qualified) types:
— integral or enumeration type,
— pointer to object or pointer to function,
— reference to object or reference to function,
— pointer to member.

A non-type template-parameter shall not be declared to have floating point, **class**, or void type. 

It is obvious that any std conforming compiler throws an error if you declare class as non type template argument.

jRJ
  • 268
  • 2
  • 5
5

Starting with C++ 20 this is now supported

The classes generally need to be a Literal Type.

Andreas H.
  • 5,557
  • 23
  • 32
  • Really? How does it work behind the scenes? – JensB Jul 13 '21 at 12:52
  • @JensB I do not how the implementation actually works, but I would guess the class members are serialized and that is used in the name mangling. So conceptually similar to a (really) wide int. There are constraints though: The class needs to be a [Literal Type](https://en.cppreference.com/w/cpp/named_req/LiteralType) which means for instance that everything relevant needs to be constexpr. if you read the requirements for LiteralType it makes sure that this serialization is actally possible and that they really behave as (compile-time) constant objects should behave. – Andreas H. Jul 13 '21 at 17:25
  • @JensB It is a really cool feature, that can even be combined with `auto` :-) – Andreas H. Jul 13 '21 at 17:32