16

The code below compiles fine with clang, but does not compile with GCC (tried 4.1.2, 4.5.4 and 4.7.2):

template <typename T>
struct A
{
    struct B { };
};

template <typename T>
bool operator==(typename A<T>::B const& b, T const&  t);

enum { BAR };

template <typename T>
bool test()
{
    return 0 == BAR;
}

The error message from GCC 4.7.2 is:

a.cpp: In instantiation of ‘struct A<<anonymous enum> >’:
a.cpp:12:6:   required by substitution of ‘template<class T> bool operator==(const typename A<T>::B&, const T&) [with T = <anonymous enum>]’
a.cpp:19:17:   required from here
a.cpp:6:12: error: ‘<anonymous enum>’ is/uses anonymous type
a.cpp:6:12: error:   trying to instantiate ‘template<class T> struct A<T>::B’
a.cpp:6:12: error: ‘<anonymous enum>’ is/uses anonymous type
a.cpp:6:12: error:   trying to instantiate ‘template<class T> struct A<T>::B’

Is GCC correct in rejecting the code, or am I hitting its bug?

P.S. I've seen this error while trying to build one of opensource projects. I tried to make smallest possible example that reproduces it.

NET3
  • 1,520
  • 1
  • 16
  • 25
iv_
  • 161
  • 3

1 Answers1

1

It is not valid C++ according to the original standard:

14.3.1 of the standard says:

2 A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template argument for a template type-parameter. [Example: ...

However I believe this was restriction was removed by the latest C++11 standard. That may explain why some compilers accept it while others reject it.

atomice
  • 3,062
  • 17
  • 23
  • 1
    As GManNickG pointed out in the comments, SFINAE. The failing overload should be silently eliminated. – MSalters Dec 04 '12 at 12:50
  • I confirm that `g++` is not compiling it until you ask for C++11 specs: `g++ -std=c++11 -o foo.o -c foo.c` – perror Dec 17 '12 at 12:44