I have this simple code:
class C0
{
public:
C0(std::string i) : i_(i) {}
private:
std::string i_;
};
class C1 : public virtual C0
{
public:
constexpr static auto const e{"e"};
C1(std::string i = e) : C0(i) {}
};
class C2 : public virtual C1
{
public:
C2(std::string k) : k_(k) {}
private:
std::string k_;
};
Compiled as: [clang++|g++] -std=c++17 example.cpp
I get the following error:
With g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0:
example.cpp: In constructor ‘C2::C2(std::__cxx11::string)’:
example.cpp:23:41: error: no matching function for call to ‘C0::C0()’
C2(std::string k) : k_(k) {}
^
example.cpp:6:17: note: candidate: C0::C0(std::__cxx11::string)
C0(std::string i) : i_(i) {}
^~
example.cpp:6:17: note: candidate expects 1 argument, 0 provided
example.cpp:3:7: note: candidate: C0::C0(const C0&)
class C0
^~
example.cpp:3:7: note: candidate expects 1 argument, 0 provided
example.cpp:3:7: note: candidate: C0::C0(C0&&)
example.cpp:3:7: note: candidate expects 1 argument, 0 provided
With clang++ version 6.0.0-1ubuntu2:
example.cpp:23:17: error: constructor for 'C2' must explicitly initialize the base class 'C0' which does not have a default constructor
C2(std::string k) : k_(k) {}
^
example.cpp:3:7: note: 'C0' declared here
class C0
^
Why does the compiler complain about missing default constructor in class C0
when the default constructor of class C1
explicitly calls C0
constructor passing the argument?
When I define a default constructor in C0
, the call to C0(i)
from C1
does not happen. So the member variable C0::i_
is not initialised. Shouldn't there be a call to C0(i)
rather than the default constructor of C0
when C2
is instantiated?
The most derived class is the one that is responsible for constructing the virtual bases. To fix this, add : C0(k)
to C2
.