The C++ standard does not allow delegate constructors and member initializers in a single mem-initializer-list, yet the following code compiles fine with clang++ and g++.
#include <iostream>
class Shape {
public:
Shape();
};
class Circle : public Shape {
public:
std::string name;
Circle(std::string name);
};
Shape::Shape() {
std::cout << "Shape constructor" << std::endl;
}
Circle::Circle(std::string name) : Shape::Shape(), name(name) { /* <--- Expected an error here! */
std::cout << "Circle constructor" << std::endl;
}
int main() {
Circle c("my_circle");
std::cout << c.name << std::endl;
return 0;
}
The relevant quote from the C++ 20 standard is (emphasis mine):
(§11.10.2/6) A mem-initializer-list can delegate to another constructor of the constructor’s class using any class-or-decltype that denotes the constructor’s class itself. If a mem-initializer-id designates the constructor’s class, it shall be the only mem-initializer; the constructor is a delegating constructor, and the constructor selected by the mem-initializer is the target constructor.[…]
Did I misread the C++ standard? Do clang++ and g++ deviate from the standard here?
>Solution :
Your issue is that you are not using a delegating constructor. A delegating constructor is a constructor for your type that is called by the constructor that was used to create the object. For example, in
struct Foo
{
Foo(int) : Foo("delegate") {} #1
Foo(std::string) {} #2
};
#1 and #2 are both constructors for Foo and constructor #1 delegates to constructor #2.
In you case you have a class that is derived from another class and in
Circle::Circle(std::string name) : Shape::Shape(), name(name)
You are initializing the Shape part of the Circle object by calling Shapes default constructor. You then move on after that to finish initializing the rest of the members of the class.