14

We're not allowed to define a functor struct inside a function because one is not allowed to use function declared structs in the instantiation of function templates.

Are there any other significant pitfalls to be aware of? E.g. would this be bad:

int foo()
{
    struct Scratch
    {
        int a, b, c;
    };
    std::vector<Scratch> workingBuffer;
    //Blah Blah
}
Billy ONeal
  • 104,103
  • 58
  • 317
  • 552
  • 1
    @Nawaz: This isn't an exact duplicate I think –  Jun 20 '11 at 18:22
  • @0A0D: The kind of question asked here, is already answered in that topic as well. Hence a possible duplicate. – Nawaz Jun 20 '11 at 18:23
  • 2
    @Billy: In that case, let me copy paste my answer from the other topic. – Nawaz Jun 20 '11 at 18:26
  • @Billy:We're here to provide information, not conform to arbitrary closing rules. The only thing that discussion did was go in the wrong direction. Instead of narrowing what is allowed to be linked to as a solution, we should broaden the close reason as "answer exists elsewhere", or something. Since I believe the latter is correct and forcing people to copy-and-paste answers is dreadfully incorrect, I'm voting to close. – GManNickG Jun 20 '11 at 18:32
  • @GMan: I would agree with a change like that. My issue is that closing as exact duplicate sounds like a reprimand -- "You idiot -- you didn't even search for the solution before asking another question?". However, there are many paths which lead to essentially the same information. – Billy ONeal Jun 20 '11 at 19:29
  • @GMan: [It seems someone has opened a new Meta discussion on the topic...](http://meta.stackexchange.com/questions/95799/closing-as-duplicate-when-the-answers-are-duplicates) you might want to weigh in there. – Billy ONeal Jun 20 '11 at 19:31
  • @GMan: Also, http://meta.stackexchange.com/questions/95805/feature-request-close-reason-answer-exists-elsewhere – Billy ONeal Jun 20 '11 at 19:34

5 Answers5

23

1. C++ standard forbids using locally-defined classes with templates.

14.3.1/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.

A code 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
    }

Here is a little more reference from IBM documentation:

2. Declarations in a local class can only use type names, enumerations, static variables from the enclosing scope, as well as external variables and functions.

A Code Example:

int x;                         // global variable
void f()                       // function definition
{
      static int y;            // static variable y can be used by
                               // local class
      int x;                   // auto variable x cannot be used by
                               // local class
      extern int g();          // extern function g can be used by
                               // local class

      class local              // local class
      {
            int g() { return x; }      // error, local variable x
                                       // cannot be used by g
            int h() { return y; }      // valid,static variable y
            int k() { return ::x; }    // valid, global x
            int l() { return g(); }    // valid, extern function g
      };
}

int main()
{
      local* z;                // error: the class local is not visible
      return 0;
}

3. A local class cannot have static data members

A Code Example:

void f()
{
    class local
    {
       int f();              // error, local class has noninline
                             // member function
       int g() {return 0;}   // valid, inline member function
       static int a;         // error, static is not allowed for
                             // local class
       int b;                // valid, nonstatic variable
    };
}
Alok Save
  • 202,538
  • 53
  • 430
  • 533
2

The scope of the local classes is the function in which they're defined.But that isn't interesting in itself1.

What makes local classes interesting is that if they implement some interface, then you can create instances of it (using new) and return them, thereby making the implementation accessible through the base class pointer even outside the function.

Some other facts about local classes:

  • They cannot define static member variables.

  • They cannot access nonstatic "automatic" local variables of the enclosing function. But they can access the static variables.

  • They can be used in template functions. They cannot be used as template argument, however.

  • If they defined inside template function, then they can use the template parameters of the enclosing function.

  • Local classes are final, that means users outside the function cannot derive from local class to function. Without local classes, you'd have to add an unnamed namespace in separate translation unit.

  • Local classes are used to create trampoline functions usually known as thunks.

Some references from the Standard (2003)

9.8 Local class declarations [class.local]

\1. A class can be defined within a function definition; such a class is called a local class. The name of a local class is local to its enclosing scope. The local class is in the scope of the enclosing scope, and has the same access to names outside the function as does the enclosing function. Declarations in a local class can use only type names, static variables, extern variables and functions, and enumerators from the enclosing scope.

[Example:

int x;
void f()
{
   static int s ;
   int x;
   extern int g();

   struct local {
      int g() { return x; } // error: x is auto
      int h() { return s; } // OK
      int k() { return ::x; } // OK
      int l() { return g(); } // OK
   };
// ...
}
local* p = 0; // error: local not in scope

—end example]

\2. An enclosing function has no special access to members of the local class; it obeys the usual access rules (clause 11). Member functions of a local class shall be defined within their class definition, if they are defined at all.

\3. If class X is a local class a nested class Y may be declared in class X and later defined in the definition of class X or be later defined in the same scope as the definition of class X. A class nested within a local class is a local class.

\4. A local class shall not have static data members.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
1

Local structs / classes can't have static data members, only static member functions. Also, they can't be templates.

Xeo
  • 129,499
  • 52
  • 291
  • 397
0

Yes. Local classes can't be used as template parameters in C++03

John
  • 2,326
  • 1
  • 19
  • 25
  • Do you have a reference? I know you're not allowed to use them for function templates' argument deduction -- but not necessarily for instantiation classes manually. – Billy ONeal Jun 20 '11 at 18:13
0

local structs are perfectly legal, even in C++98. You cannot use them with templates in C++98 though, whereas you can in C++0x. g++ 4.5 supports using local structs with templates in -std=c++0x mode.

  • I think ideone uses c++0x 4.5, but it still gives error for local `template struct` http://www.ideone.com/5xhWE – iammilind Jun 22 '11 at 03:57