4

Let's say I have the following snippet:

template <class T> void f(T arg) { arg(); }

void g()
{
   struct { void operator()(void) { } } foo;

   f(foo);
}

Visual C++ accepts this. However, when I try GCC, I get:

$ g++ --version # just in case this matters
g++ (Debian 4.4.5-8) 4.4.5
...
$ g++ foo.cc
foo.cc: In function 'void g()':
foo.cc:7: error: no matching function for call to 'f(g()::<anonymous struct>&)'

When foo is scoped globally and its type has a name, this works. But when the type is anonymous or declared inside g() it does not.

Why does GCC reject this? Is it valid C++?

asveikau
  • 39,039
  • 2
  • 53
  • 68

2 Answers2

7

14.3.1 paragraph 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 templateargument for a template typeparameter.

In other words, not valid. Although it would be handy imo, that's maybe why VC allows it.

stijn
  • 34,664
  • 13
  • 111
  • 163
  • 2
    frustrating, indeed. This would have been a workable alternative to the lack of closures in C++ for instance. – Alexandre C. Jan 11 '11 at 15:27
  • 1
    Thanks for such a straightforward answer. To me it seems like this usage fits the "spirit" of the language, but I can also see why this might have been scoped out to save implementers some hassle. – asveikau Jan 11 '11 at 15:53
  • 1
    exactly. It's a pitty one has to clutter the global or other namespaces with structs that don't really belong there but just get used once in a single function.. – stijn Jan 11 '11 at 15:56
  • 1
    you can always use unnamed-namespaces for those kind of functors! – ltjax Jan 11 '11 at 16:34
2

As already said, a local class (a class defined within a function) can not be used as a template argument. Fortunately, C++0x fixes that with lambda functions: http://en.wikipedia.org/wiki/C%2B%2B0x#Lambda_functions_and_expressions

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271