Question

I have a function like this:

Object Class::function() {
    Object o;
    return o;
}

Now when I call it like this:

Object o = Class::function();

it wants to use the move constructor. However I want it to use the copy constructor. How do I force it to not use the move constructor? I deleted the move constructor but then it won't compile.

EDIT: My constructors look like this:

Object(const Object & other) { ... }
Object(Object & other) { ... }
Object(Object && other)=delete;
Was it helpful?

Solution

If you have a user-declared (manually declared) copy ctor, the move ctor will not be declared implicitly. Just leave out the move ctor, and it won't take part in overload resolution (i.e. don't define it as deleted, just leave out the entire declaration).

After CWG DR 1402, the explanation is slightly different: a move ctor will always be declared even if there's a user-declared copy ctor, but it will be implicitly defined as deleted. And there's a special case for this deletion that makes the move ctor not take part in overload resolution. Note: If you explicitly delete the move ctor, that still means "if this function is selected by overload resolution, the program is ill-formed". The special case applies when the move ctor is defaulted (explicitly or implicitly), and when this leads to the move ctor being defined as deleted (as the implicit definition supplied for a defaulted function).

#include <iostream>

struct loud
{
    loud() { std::cout << "default ctor\n"; }
    loud(loud const&) { std::cout << "copy ctor\n"; }
    loud(loud&&) { std::cout << "move ctor\n"; }
    ~loud() { std::cout << "dtor\n"; }
};

struct foo
{
    loud l;
    foo() = default;
    foo(foo const& p) : l(p.l) { /*..*/ }; // or `= default;`
    // don't add a move ctor, not even deleted!
};

foo make_foo()
{
    return {{}};
}

int main()
{
    auto x = make_foo();
}

Watch out for copy elision (e.g. use -fno-elide-constructors). Output:

default ctor
copy ctor
dtor
dtor

Live example

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top