Why adding `explicit` to a defaulted copy constructor prevents returning an object?

123 Views Asked by At

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?

1

There are 1 best solutions below

0
Cory Kramer On BEST ANSWER

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)'
}