1

I'm trying to use an instant of a custom class as a template parameter.

class X {
public:
  X() {};
};

template <class Foo, Foo foo>
struct Bar {

};
const X x;
Bar<X, x> foo;

The compiler states that x cannot appear in a constant expression. Why that? There is everything given to construct that object at compile time.

nils
  • 4,649
  • 3
  • 19
  • 8

3 Answers3

7

You can't do it. Standard 14.1 says:

4 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.
5 [ Note: other types are disallowed either explicitly below or implicitly by the rules governing the form of template-arguments (14.3). —end note ] The top-level cv-qualifiers on the template-parameter are ignored when determining its type.

Tadeusz Kopec for Ukraine
  • 12,283
  • 6
  • 56
  • 83
  • Which *are* a lot of options after all. Any POD (excluding floating-point values and dynamic pointers) can be translated into a template, it just can't be converted automatically by the compiler. – Potatoswatter Mar 26 '10 at 08:38
  • In C++0x we are finally allowed to pass class types as arguments, as long as they have a constexpr conversion function to integral or enum types. – Johannes Schaub - litb Mar 31 '10 at 17:41
0

As others have pointed out you can't do it. So long as you are not playing meta-programming games, the normal way to pass an actual instance of a class is in the constructor:

template <class Foo>
struct Bar {
    Bar( const Foo & f ) {
      ...
    }
};
-1

Template parameters can be types, or integral constants. X is a type, but x is not. You also can't use constant floating point values.

Dennis Zickefoose
  • 10,791
  • 3
  • 29
  • 38