[ACCEPTED]-Usage of local class in C++ function-design-patterns

Accepted answer
Score: 51

What's the scope of internal struct of "struct 46 Object"?

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

What makes 43 local classes interesting is that if they 42 implement some interface (like your code 41 does), then you can create instances of 40 it (using new) and return them (for example, as 39 std::vector<IBase*>), thereby making the implementation accessible through the base class pointer even outside 38 the function.

Some other facts about local 37 classes:

  • They cannot define static member 36 variables.

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

  • They can 33 be used in template functions.

  • If they are 32 defined inside a template function, then 31 they can use the template parameters of 30 the enclosing function.

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

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


Some references from the Standard 23 (2003)

9.8 Local class declarations [class.local]

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


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 13 function has no special access to members 12 of the local class; it obeys the usual 11 access rules (clause 11). Member functions 10 of a local class shall be defined within their 9 class definition, if they are defined 8 at all.

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

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

Score: 8

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

BUT you can do this, inside 2 of a local class

int GetCount()
    class _local
        static int Count(int count = std::numeric_limits<int>::max())
            static int count_ = 0;
            if (count != std::numeric_limits<int>::max()) count_ = count;
            return count_;

        static float Operation(float  a, float  b)
            _local::Count(_local::Count() + 1);
            return a;
   CALLBACK( _local::Operation);
   return _local::Count();

_local::Count can be used 1 to read and write the otherwise static variable


Score: 3

This is normal C++. The scope of struct Object is only the 4 function func. However, you can still use objects 3 of this type without knowing which concrete 2 type they are, since they inherit from IBase. This 1 is used to encapsulate implementation.

Score: 2

A very interesting use of a local class 13 is presented by Jason Turner in his CppCon 12 talk focused on programming of Commodore 11 64 game in C++17. He shows how to use the 10 RAII principle on the function level.

He 9 basically establishes invariants in the 8 constructor of a local class in a function 7 returning an instance of this class. The 6 invariants duration is thusly controlled 5 by the lifetime of the returned object. It 4 is quite similar to what RAII wrappers like 3 std::lock do, just slightly different.

You can see the appropriate part here, but 2 I love his performance and recommend to see 1 it all the way through.

More Related questions