BЈовић
BЈовић

Reputation: 64223

How to declare a constant that is used in a template?

I have a template that depends on a constant which is in a header. Something like this :

  1. The header that defines the constant:

    // header1.hpp
    const int CONST_VALUE1 = 10;
    
  2. The header where I have a template :

    // header2.hpp
    extern const int CONST_VALUE2;
    
    template< int N >
    struct A
    {
    };
    struct B
    {
      // some member functions
      A< CONST_VALUE2 > a;
    };
    
  3. the source with the definition of B and the constant

    // source2.hpp
    #include "header2.hpp"
    // implementation of B
    const int CONST_VALUE2 = CONST_VALUE1;
    

This of course doesn't work. The error is like this :

error: the value of 'CONST_VALUE2' is not usable in a constant expression
note: 'CONST_VALUE2' was not initialized with a constant expression
note: in template argument for type 'int'

Is there a work around? Or do I have to include the header1.hpp into header2.hpp?

Upvotes: 4

Views: 4972

Answers (4)

lmcdowall
lmcdowall

Reputation: 443

Templates are evaluated when compiled and thus all the template arguments must be known and constant at that point. By declaring your variable as extern the compiler doesn't know the value when it evaluates the template and thus gives the error your seeing.

You will need to ensure that the template argument is a known value when the template is compiled.

Upvotes: 0

BЈовић
BЈовић

Reputation: 64223

This answer tells that the extern const is not going to work.

However, I figured a work around :

  1. change the header2.hpp to define the constant :

    const int CONST_VALUE2 = 10;
    
  2. change the source file to check the constant :

    #include "header2.hpp"
    // implementation of B
    static_assert( CONST_VALUE2 == CONST_VALUE1, "check the constant!" );
    

This way the header2.hpp doesn't have to include header1.hpp (it is needed only in the source file).

Upvotes: 0

Unknown1987
Unknown1987

Reputation: 1701

header1 has to be visible to header2. The templated class does not know how to instantiate itself unless it has all its definitions.

Upvotes: 0

James Kanze
James Kanze

Reputation: 153909

A template requires a constant expression for a non-type parameter. For a const variable to be used in a constant expression, its initialization must be visible to the compiler. So you'll probably have to include header1.hpp in header2.hpp.

Upvotes: 1

Related Questions