5

In C++, single use structures and classes can be declared unnamed, if an object is created directly:

struct { int x; int y; } point;

Unnamed classes may also inherit from a base class. This is for example useful to create a list of different "processors" from a base processor interface. Here a simple example:

struct Processor {virtual int op(int a, int b) = 0;};
struct : Processor {int op(int a, int b) override { return a+b; }} Adder;
struct : Processor {int op(int a, int b) override { return a*b; }} Multiplier;

So both Adder and Multiplier become single derived objects of the Processor interface. But what, if the base Processor has more structure and has a constructor, that requires parameters? Let's see this example:

class Processor {
private:
    std::string name;
public:
    virtual int op(int a, int b) = 0;
    const std::string& getName() const { return name; }
    Processor(std::string name) : name(name) {}
};

How does one create an unnamed subclass for this Processor, for example an "Adder". The naive attempt:

class : public Processor {
public:
    int op(int a, int b) override { return a + b; }
} Adder { "Adder" };

unfortunately fails, because the unnamed class has no implicitely generated constructor, that would accept "Adder" as its argument. And explicitely declaring such a constructor is not possible, either, because it is not possible to declare constructors in unnamed clases: The constructor is named the same as the class, but if there is no class name, then there is no constructor name, either.

I know, that there are easy workarounds: One is to give a name after all (potentially in a namespace) and then use that to declare a constructor. One might also be tempted to use a virtual init() method, that is called from the constructor of Processor, and which does the work, that the constructor is supposed to do. But this doesn't work, as the virtual call in the constructor doesn't reach the method in the derived class, yet. But, instead, the call to init() could be hidden in the initializer of a data member of the unnamed class.

But is there any "pure" C++ answer, which keeps the unnamed class unnamed and still does everything in the constructor, that should be done in the constructor?

Kai Petzke
  • 2,150
  • 21
  • 29

1 Answers1

4

While writing this question, I found the answer already, so I will share it here: With C++11, the using keyword was extended to allow the explicit import of the constructors of the base class, and this solves the problem neatly:

class : public Processor {
using Processor::Processor;
public:
    int op(int a, int b) override { return a + b; }
} Adder { "Adder" };

So Adder is instantiated correctly at program startup and the namespace is kept safe from pollution.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
Kai Petzke
  • 2,150
  • 21
  • 29