Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

CRTP base private constructor and derived friend class cause compilation error using C++17 and uniform initialization

I’ve got the following code:

struct B
{
  B(int) {}
};

template <typename T>
class Base : public B
{
  friend T;
  Base() : B(1) {}
};

class Derived : public Base<Derived>
{
public:
    void do_sth() const {}
};

int main()
{
  auto x = Derived{}; //Compiles only when using C++11
  auto x1 = Derived(); //Compiles using C++17/20 flag
  x.do_sth();
  x1.do_sth();
} 

For some reason when using C++17 compilation fails due to ‘non-compilable’ initialization of ‘x’ variable. Compilator says that:

Base::Base() [with T = Derived]’ is private within this context

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

but as you can see, below I’m creating an object of the same type but this time I’m not using uniform initialization.
x1 variable can be compiled using both C++11 or C++17 standards, but the ‘x’ variable is compilable only in C++11 mode. Why is that? What has changed in the standard that causes this problem?

Compiler explorer

>Solution :

Apparently Derived is an aggregate since C++17, so Derived{} is an aggregate initialization. (Base classes weren’t allowed in aggregates pre-C++17, now public non-virtual bases are allowed.)

Meaning Base::Base() is invoked directly by the caller (main()), rather than Derived.

The solution is to add Derived() {} to Derived to stop it from being an aggregate.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading