Reputation: 64223
I have a template that depends on a constant which is in a header. Something like this :
The header that defines the constant:
// header1.hpp
const int CONST_VALUE1 = 10;
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;
};
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
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
Reputation: 64223
This answer tells that the extern const
is not going to work.
However, I figured a work around :
change the header2.hpp to define the constant :
const int CONST_VALUE2 = 10;
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
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
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