2

Why does this

#include <vector>

void f()
{
    struct S
    {
        int first, second, third;
    };

    std::vector<S> vs;
}

work with Visual C++ 2015, but not with g++ 4.8.4?

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
Bonita Montero
  • 2,817
  • 9
  • 22

1 Answers1

8

Ensure you are compiling with at least -std=c++0x.

In C++11, the standard was modified to allow for local classes to be template arguments (for lambda support). If you target pre-C++11, this won't work.

If you're compiling MSVC, it will enable C++11 by default, which is not so with clang and pre-gcc 6

See also: What restrictions does ISO C++03 place on structs defined at function scope?

Community
  • 1
  • 1
AndyG
  • 39,700
  • 8
  • 109
  • 143
  • Might be worth mentionning that this support is on by default in MSVC? (It's been mentioned in the comments but still) – Borgleader Feb 07 '17 at 18:28
  • "classes to be local to functions" That was allowed in C++98. What was not allowed was to use them as template type parameters . – peppe Feb 07 '17 at 18:29
  • I was going to ask why C++11 allows local structs. Didnt know that before. When you say "for lambda support" is it something going on behind the scenes when I declare a lambda or something supposed to be used with lambdas? – 463035818_is_not_an_ai Feb 07 '17 at 18:36
  • 4
    @tobi303 A lambda is a unnamed class type. It looks like an expression but that is just syntactic sugar. The compiler actually builds a class type with what you provide in the expression. – NathanOliver Feb 07 '17 at 18:37
  • 1
    @NathanOliver: And to be slightly more formal, the standard requires that a lambda be a class "The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed nonunion class type" [expr.prim.lambda] – AndyG Feb 07 '17 at 18:40
  • @NathanOliver thx. So a lambda is kind of the same thing as a local functor – 463035818_is_not_an_ai Feb 07 '17 at 18:40
  • @tobi303 Exactly. It is just a nice short way to be able to write it. Think of them as throw away objects basically. You really should only be using them for something where a named object really isn't need but a object would be nice to have. – NathanOliver Feb 07 '17 at 18:42
  • That doesn't quite explain what lambdas have to do with allowing local classes as template type parameters... – peppe Feb 07 '17 at 19:16
  • 1
    @peppe: Consider `std::copy_if` - its predicate is a template type parameter, and a typical use case of a lambda. – MSalters Feb 08 '17 at 08:55