When I compile the following snippet with g++
template<class T>
class A
{};
template<class T>
class B
{
public:
typedef A<T> A;
};
the compiler tells me
error: declaration of ‘typedef class A<T> B<T>::A’
error: changes meaning of ‘A’ from ‘class A<T>’
On the other hand, if I change the typedef to
typedef ::A<T> A;
everything compiles fine with g++. Clang++ 3.1 doesn’t care either way.
Why is this happening? And is the second behavior standard?
g++ is correct and conforming to the standard. From [3.3.7/1]:
Before the typedef,
Areferred to the::A, however by using the typedef, you now makeArefer to the typedef which is prohibited. However, sinceno diagnostic is required, clang is also standard conforming.jogojapan’s comment explains the reason for this rule.
Take the following change to your code:
Because of how class scope works,
A a;becomes ambiguous.