1

The following snippet doesn't compile, and I'm not exactly sure why:

#include <iostream>

class A {
    public:    
    A(int val) { std::cout << "A default is called" << std::endl;
                    m_val = val;};
    A(A && other) { std::cout << "A move constructor is called" << std::endl;
        m_val = other.m_val;
        other.m_val = 0;}
    int m_val;
};

class B : public A {
    public:
    using A::A;
    B() : A(5) { std::cout << "B default is called" << std::endl; };
};

class C : public B {
    public:
    using B::B;
    C() { std::cout << "C default is called" << std::endl; };
};

A createA(int val) { return A(val); }
C createC() { return C(); }

int main()
{
    C objC(createA(10));
    return 0;
}

I would expect C to inherit the move constructor from B, which inherits from A. but I get the following error:

adam$ clang++ -std=c++17 test.cpp -o test
test.cpp:30:7: error: no matching constructor for initialization of 'C'
    C objC(createA(10));
      ^    ~~~~~~~~~~~
test.cpp:5:5: note: candidate inherited constructor not viable: no known conversion from 'A' to 'int' for 1st argument
    A(int val) { std::cout << "A default is called" << std::endl;
    ^
test.cpp:21:14: note: constructor from base class 'B' inherited here
    using B::B;
             ^
test.cpp:19:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'A' to 'const C' for 1st argument
class C : public B {
      ^
test.cpp:19:7: note: candidate constructor (the implicit move constructor) not viable: no known conversion from 'A' to 'C' for 1st argument
class C : public B {
      ^
test.cpp:22:5: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
    C() { std::cout << "C default is called" << std::endl; };
    ^
1 error generated.

Why isn't the move constructor inherited all the way from A to C?

Adam
  • 161
  • 2
  • 14
  • I think you can make a more minimal example by removing C entirely and try to construct a `B` [like this](https://godbolt.org/z/o-jskw) (I removed a bunch of other stuff too). So now your question can change to *Why aren't move constructors inherited?* – Kevin Dec 10 '18 at 15:57
  • gcc offers this error message aswell. `note: an inherited constructor is not a candidate for initialization from an expression of the same or derived type` – super Dec 10 '18 at 15:57
  • @Kevin in my original example there were 3 objects (just like in this example) so I thought that was the problem, but actually in your example it's also not working... so I guess the source of the problem isn't C not being a direct Derived of A, but I'm still not sure why it happens. – Adam Dec 10 '18 at 16:01

0 Answers0