Possible Duplicate:
GCC problem : using a member of a base class that depends on a template argument
I thought I was familiar with C++, but apparently not familiar enough.
The problem is when you define a constant in a template class, you can use the constant in new classes that derive from that class, but not new template classes that derive from it.
For example, gcc says
test.h:18: error: ‘theconstant’ was not declared in this scope
when I try to compile this (simplified) header file:
#pragma once
template <typename T> class base
{
public:
static const int theconstant = 42;
};
class derive1 : public base<size_t>
{
public:
derive1(int arg = theconstant) {}
};
template<typename T> class derive2 : public base<T>
{
public:
derive2(int arg = theconstant) {} // this is line 18
};
So the problem is that one class, derive1
, compiles fine, but the other class, derive2
, which is a template specialisation, does not.
Now maybe gcc's error is not clear enough, but I don't understand why the constructor in derive2
would have a different scope than the one in derive1
.
In case it matters, this happens during compilation of the header file itself, not when instantiating an object of type derive2<type>
.
I also know what to change to make this compile, so I'm not really looking for one-line pieces of code as answers. I want to understand why this happens! I tried searching the web, but apparently I'm not using the correct search arguments.
I am pretty sure this will help you understand:
Your code which does not compile:
template<typename T> class derive2 : public base<T>
{
public:
derive2(int arg = theconstant) {} // this is line 18
};
And the reason why:
template <> class base<size_t>
{
public:
static const int ha_idonthave_theconstant = 42;
};
derive2<size_t> impossible_isnt_it;
The specialization!!! Compiler at your line 18 cannot be sure that you will not specialize the base<> in the way that this constant will not be present there at all.
Try
template<typename T> class derive2 : public base<T>
{
public:
derive2(int arg = base<T>::theconstant) {} // this is line 18
};
Basically you've specified the incomplete scope for the "theconstant".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With