21

Is there any change in the usage of local class in C++11?

It seems in C++03 local classes cannot be used as template argument (I recall that).

Consider this code,

template<typename T> void f(const T&) {}

//Note : S is a local class defined inside main()
int main() { struct S{};  f(S()); } //I want template argument to be deduced.

But it gives compilation error (C++03 mode), saying (ideone):

prog.cpp:4: error: no matching function for call to ‘f(main()::S)’

However, it compiles fine when compiling it in C++11 mode (ideone), which makes sense to me, otherwise lambda wouldn't work. So I guess that there is at least this change in the usage of local classes. Am I right? What are other changes concerning local classes?

Please quote the relevant text from the Standards (C++03 and C++11 both) so readers can compare themselves, and for future reference.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • At least in older C++ standards you could not instantiate templates using local types. – Paul Manta Nov 20 '11 at 18:52
  • I distinctly remember this as a change from C++03 to C++11. The restriction local classes vs templates was more arbitrary than anything and I am not sure that it eased the writing of compilers (removing the local concepts *would* ease it, once you parsed them though, what's to gain ?). I don't have the C++03 Standard though, so you'll have to take my word for it until someone comes that has it. – Matthieu M. Nov 20 '11 at 18:56
  • 4
    There was a [paper](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1427.pdf) about this. – Mankarse Nov 20 '11 at 19:05
  • @Mankarse: Thanks. That looks quite interesting. Will read it. – Nawaz Nov 20 '11 at 19:07

3 Answers3

12

The differences are visible by comparing §14.3.1/2 in both standards.

  • C++03

    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:

    template <class T> class X { /* ... */ };
    void f()
    {
     struct S { /* ... */ };
     X<S> x3;        // error: local type used as template-argument
     X<S*> x4;        // error: pointer to local type used as template-argument
    }
    

    —end example] [Note: a template type argument may be an incomplete type (3.9). ]

  • C++0x (n3290)

    [ Example:

    template <class T> class X { };
    template <class T> void f(T t) { }
    struct { } unnamed_obj;
    
    void f() {
     struct A { };
     enum { e1 };
     typedef struct { } B;
     B b;
     X<A> x1;        // OK
     X<A*> x2;       // OK
     X<B> x3;        // OK
     f(e1);          // OK
     f(unnamed_obj); // OK
     f(b);           // OK
    }
    

    — end example ] [ Note: A template type argument may be an incomplete type (3.9). — end note ]

C++03 explicitly disallows local classes in template type arguments. C++11 doesn't, and even includes an example of a valid use of such.

Mat
  • 202,337
  • 40
  • 393
  • 406
10

From older standard:

(14.3) 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.

It seems to be removed in the C++11 standard.

More restrictions:

(9.8) Declarations in a local class can use only type names, static variables, extern variables and functions, and enumerators from the enclosing scope.

(9.8) A local class shall not have member templates.

(14.5.4) A friend template shall not be declared in a local class.

(9.4.2 ) A local class shall not have static data members.

(9.3) Member functions of a local class (9.8) have no linkage.

Pubby
  • 51,882
  • 13
  • 139
  • 180
  • Are there any reasons for the rest of the restrictions that were not lifted from local classes? – the_drow Nov 21 '11 at 00:41
  • "A local class shall not have member templates" is in 14.5.2. "A local class shall not have static data members" is in 9.8. Just to clarify, all these restrictions remain in C++11. – Potatoswatter Nov 21 '11 at 09:58
2

According to my own question the limitation is removed and local classes can be used as template arguments.
I see no reference to the new standard though.

Community
  • 1
  • 1
the_drow
  • 18,571
  • 25
  • 126
  • 193