0

Considering this MRE (the real case involves some class with some inheritance and some member variables)

class A {
    public:
    
    A() = default;
    explicit A(const A&) = default;
    // explicit A(A&) = default; ///Adding this serves no purpose
    explicit A(A&&) = default;
    A& operator=(const A&) = default;
    A& operator=(A&&) = default;
};

auto dummy_a() {
    A a;
    return a; //no matching function for call to 'A::A(A)'
}

int main() {
    const auto a = dummy_a();
}

I get the following error unless I remove explicit from either the copy or the move constructor. (Can be tested here)

main.cpp: In function 'auto dummy_a()':
main.cpp:14:12: error: no matching function for call to 'A::A(A)'
   14 |     return a; //no matching function for call to 'A::A(A)'
      |            ^
main.cpp:4:5: note: candidate: 'constexpr A::A()'
    4 |     A() = default;
      |     ^
main.cpp:4:5: note:   candidate expects 0 arguments, 1 provided

Why is that the case?

Antonio
  • 19,451
  • 13
  • 99
  • 197
  • 4
    By making the copy and move constructor explicit, you make it impossible for the compiler to user either to return `a` without you first explicitly asking for it. `return A{a};` should work instead. – François Andrieux Nov 10 '22 at 14:36
  • is the "non const" actually relevant? Its the same error whith `const A a; return a;`, no? – 463035818_is_not_an_ai Nov 10 '22 at 14:37
  • @463035818_is_not_a_number you are right, removed `const` from the text of my question – Antonio Nov 10 '22 at 14:44
  • [Dupe1](https://stackoverflow.com/questions/35688633/how-come-i-cant-use-explicit-constructor-for-constructing-a-return-type) and [Dupe2](https://stackoverflow.com/questions/11480545/explicit-copy-constructor). – Jason Nov 10 '22 at 14:56

1 Answers1

3

In your function dummy_a your return value requires implicit copy construction

auto dummy_a() {
    A a;
    return a; // implicit 'A::A(A)'
}

If you indeed want your copy constructor to be explicit then this should be modified to

auto dummy_a() {
    A a;
    return A{a}; // explicit 'A::A(A)'
}
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218