55

Given the following code:

void f()
{
    class A
    {
        template <typename T>
        void g() {}
    };
}

g++ 4.4 (and also g++-4.6 -std=gnu++0x) complains: "invalid declaration of member template in local class".

Apparently local classes are not allowed to have template members. What is the purpose of this limitation? Will it be removed in C++0x?

Note: If I make the local class itself a template, rather than giving it a template member:

void f()
{
    template <typename T>
    class A
    {
        void g() {}
    };
}

I get "error: a template declaration cannot appear at block scope".

Yun
  • 3,056
  • 6
  • 9
  • 28
HighCommander4
  • 50,428
  • 24
  • 122
  • 194
  • 1
    I came across this old question while struggling with g++-4.6. It still complains, so I edited the question a little. Hopefully we'll get more answers! – Aaron McDaid Jan 11 '12 at 18:22
  • @AaronMcDaid: Unfortunately, there isn't much more to say at this point. As litb pointed out in his comment to Crazy Eddie's answer, C++11 did **not** add support for local classes which are templates or have template members (it added support for using local classes as template parameters to another (nonlocal) class, but that's a different feature). So, g++ is not expected to support this in the near future, except perhaps as a compiler extension. I think it's a shame because it would've been a useful feature, but hey, there's always C++24... – HighCommander4 Jan 11 '12 at 19:16
  • c++14 allows generic lambdas to be defined locally with variadic arguments. These are very close to being templates and therefore might be a suitable workaround – Aaron McDaid Jul 12 '15 at 20:14
  • @HighCommander4 It's 2022, yet not supported. – Rohan Bari Nov 28 '22 at 04:07

1 Answers1

12

The purpose of this limitation? Just a guess, but:

  • you may use the template class/template member function only within the enclosing function. Therefore you already know all used types within the function and hence can directly specify the used types (for several types, of course, the template variant would have saved some typing).
  • although it might not seem so, it is work for all compiler creators and space for bugs and so it must be worth the effort.

Fun Fact: Try to use a local class within a function as a return type for a (c++0x)-lambda function declared in the function: MSVC 2010: internal compiler error ^^.

eci
  • 2,294
  • 20
  • 18
  • 4
    You might know the types used, but it still prevents you from using SFINAE tricks without exposing the helper structs. – riv Jun 25 '16 at 20:26
  • 4
    Actually when the local class is a visitor used with boost::apply_visitor on a boost::variant you _don't_ know the type. – Giel Oct 28 '16 at 12:51
  • 5
    Nor do you know the types involved if the function is in itself a template. This limitation is most likely to make it easier on compiler writers, though I can't see why. Should be able to reuse the code that is for non-local templates. – Adrian Nov 06 '17 at 14:38
  • This doesn't make sense since you might which functions are required for you, but you have still to write them manually. – Bonita Montero Oct 06 '21 at 16:03