template<typename T>
class Base
{
protected:
Base() {}
T& get() { return t; }
T t;
};
template<typename T>
class Derived : public Base<T>
{
public:
Base<T>::get; // Line A
Base<T>::t; // Line B
void foo() { t = 4; get(); }
};
int main() { return 0; }
If I comment out lines A and B, this code compiles fine under Visual Studio 2008. Yet when I compile under GCC 4.1 with lines A and B commented, I get these errors:
In member function ‘void Derived::foo()’:
error: ‘t’ was not declared in this scope
error: there are no arguments to ‘get’ that depend on a template parameter, so a declaration of ‘get’ must be available
Why would one compiler require lines A and B while the other doesn’t? Is there a way to simplify this? In other words, if derived classes use 20 things from the base class, I have to put 20 lines of declarations for every class deriving from Base! Is there a way around this that doesn’t require so many declarations?
GCC is right in this case, and Visual Studio mistakenly accepts a malformed program. Have a look at the section on Name lookup in the GCC manual. Paraphrasing:
You can get around this in either of three ways:
Base<T>::get()this->get()(There is also a fourth way, if you want to succumb to the Dark Side:
But I would recommend against that, both for the reason mentioned in the manual, and for the reason that your code will still be invalid C++.)