25

I have seen anonymous classes in C++ code on Quora. It's successfully compiled and run.

Code here:

#include <iostream>

auto func()
{
    class // no name
    {
      public:
             int val;
    } a;

    a.val = 5;

    return a;
}

int main()
{
    std::cout << func().val << std::endl;
    return 0;
}

So, Is it valid in C++?

Also, I am curious to know, Is it possible to use anonymous classes in C++?

msc
  • 33,420
  • 29
  • 119
  • 214
  • 3
    It's kinda been [asked before](https://stackoverflow.com/questions/3612164/c-anonymous-class-initialization) – Bartek Banachewicz May 25 '17 at 07:13
  • 1
    C++ has [anonymous unions](http://eel.is/c++draft/class.union.anon), but no anonymous classes/structs, which some compilers provide as an extension. Still, unnamed classes as shown in the question are valid. – cpplearner May 25 '17 at 07:56
  • 1
    @cpplearner an anonymius union is a class *member* of a union type which has no name (the member, not the type). – n. m. could be an AI May 25 '17 at 10:55
  • @n.m usually an "anonymous" class/union means such that has both no name, but also no object instantiated. Its members become members of the enclosing class scope or function's block scope. An unnamed class simply means there's no name, but otherwise it's a usual class with an object declared immediately. C++ doesn't have anonymous classes, but anonymous unions. – Johannes Schaub - litb May 25 '17 at 12:08
  • 2
    @JohannesSchaub-litb I just looked it up in the standard and it says that an anonymous union is a particular form of a union that defines an unnamed object of an unnamed type. I was wrong assuming it can only be a member of another class. – n. m. could be an AI May 25 '17 at 12:27

3 Answers3

32

Not only that, you can create more instances of the class by using decltype.

#include <iostream>

class 
{
   public:
      int val;
} a;


int main()
{
   decltype(a) b;
   a.val = 10;
   b.val = 20;

   std::cout << a.val << std::endl;
   std::cout << b.val << std::endl;
   return 0;
}

Output:

10
20
R Sahu
  • 204,454
  • 14
  • 159
  • 270
  • 1
    Is it true that before C++11 there was no way to do declare another instance of an unnamed class? – lisyarus May 25 '17 at 09:34
  • 4
    @lisyarus: It was possible with a template like `template T create(const T& prototype) { return T(); }` – Alexandre C. May 25 '17 at 10:48
  • @AlexandreC. But how do I assign the result of `create` to a local variable if I don't have access to the type (outside of `create`)? – lisyarus May 25 '17 at 11:55
  • I don't think it was possible before C++11, because you couldn't pass such objects to templates (types had to have external linkage). I could be misremembering though. The above code, which declares `a` at namespace scope, would be ill-formed in C++03, because objects with linkage (`a` has external linkage) require types with linkage, but the type has no linkage. I believe that C++11 changed rules here, but again I'm not completely certain. – Johannes Schaub - litb May 25 '17 at 12:10
  • 1
    @lisyarus That is known as moving the goalposts! `template void create(const T& prototype) { T t; }` creates a local variable of type matching an anonymous type. – Yakk - Adam Nevraumont May 25 '17 at 15:39
  • @Yakk I mean declaring an instance of an unnamed class in the same scope as the class declaration. – lisyarus May 25 '17 at 17:53
20

In C++, an anonymous union is a union of this form:

 union { ... } ;

It defines an unnamed object of an unnamed type. Its members are injected in the surrounding scope, so one can refer to them without using an <object>. prefix that otherwise would be necessary.

In this sense, no anonymous classes (that are not unions --- in C++ unions are classes) exist.

On the other hand, unnamed classes (including structs and unions) are nothing unusual.

union { ... } x;
class { ... } y;
typedef struct { ... } z;

x and y are named object of unnamed types. z is a typedef-name that is an alias for an unnamed struct. They are not called anonymous because this term is reserved for the above form of a union.

[](){}

Lambdas are unnamed objects of unnamed class types, but they are not called anonymous either.

n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
10

It was always possible to write something like this:

typedef struct { int a; } type;

Now, if you look at struct { int a } part, this is an anonymous struct. In C++, there's basically no difference between structs and classes (Except the default access modifiers). So, it's possible to have anonymous structs/classes.

nakiya
  • 14,063
  • 21
  • 79
  • 118