g++ template bug or VC too liberal?
I am writing a heavily templated piece of code in C++. It worked perfectly in VS 2005 but when I try to compile it in g++ I get some really strange errors.
The essential piece of code (simplified to a minimum, doesn't compile either) is as follows:
template <class Actual>
class Generic
{
public:
typedef Actual ThisType;
};
template <class Actual>
class Intermediate : public Generic<Actual>
{
};
template <class Q>
class Derived : public Intermediate<Derived<Q> >
{
public:
void FooBar()
{
ThisType q;
}
};
The error is: "'ThisType' was not declared in this scope" in the line where 'q' is being declared.
Curiously, everything works fine when Derived is not a template but a plain class. Why would compiler look into template function implementation b开发者_开发百科efore it is even instantiated? I know that VC++ checks far too little when compiling templates (unused templates can even contain syntactically incorrect code) - but isn't g++ checking too much here? I tried adding a typename keyword with little hope and it fails too. Is there any way to get ThisType to work as expected? I dread the thought of adding it manually to every single derived class - it's cumbersome, redundant, inelegant and error-inducing.
Best regards, MZ
Unqualified names are not looked up in dependent base classes (your base class depends on template parameter Q
). Qualify that name, and it will work.
typename Derived::ThisType q;
Trust in Comeau online compiler!
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions
"ComeauTest.c", line 19: error: identifier "ThisType" is undefined
ThisType q;
^
"ComeauTest.c", line 19: error: expected a ";" (perhaps on the previous statement)
ThisType q;
^
2 errors detected in the compilation of "ComeauTest.c".
Dependent type names from inherited classes are not taken into account, you might try to explicitly request ThisType:
typename Intermediate<Derived<Q> >::ThisType q;
The code is indeed ill-formed. When base class depends on template parameter it is not considered by name lookup when looking for unqualified names.
In your case unqualified name ThisType
will not be looked up in base class Intermediate<Derived<Q> >
because your base class depends on template parameter Q
.
You are missing a typename
template <class Actual> class Generic { public:
typedef Actual ThisType; };
template <class Actual> class Intermediate : public Generic<Actual> { };
template <class Q> class Derived : public Intermediate<Derived<Q> > { public:
void FooBar()
{
typename Derived::ThisType q;
return *this;
} };
int main(){}
精彩评论