LibertyPaul
LibertyPaul

Reputation: 1167

C++ how to avoid ambiguous move constructors

I have a class with a couple of fields, assignment c-tor and move c-tor:

class A{
    std::vector<int> numbers;
    int k;


public:

    A(std::vector<int> &&numbers, const int k):
        numbers(numbers), // fast
        k(k)
    {
        // logic
    }

    A(const std::vector<int> &numbers, const int k):
        A(std::move(std::vector<int>(numbers)), k) // copy-and-move vector
    {
        // empty
    }
};

I want to keep logic in one c-tor and call it from others. Also, I want to support fast move-semantics. And I have to explicitly copy-and-move arguments in the assignment c-tor.

Is there any way to avoid such nested construction and keep all advantages I've listed above?

Upvotes: 1

Views: 1070

Answers (1)

Kerrek SB
Kerrek SB

Reputation: 477070

You could delegate one constructor to the other:

struct A
{
    A(const std::vector<int> & v) : A(std::vector<int>(v)) {}

    A(std::vector<int> && v)
    : v_(std::move(v))
    {
        // logic
    }

    // ...
};

The moving constructor is now as fast as it can be, and the copying constructor costs one more move than if you spell both constructors out. If you're willing to pay an extra move, though, you might as well just have a single constructor:

struct A
{
    A(std::vector<int> v)
    : v_(std::move(v))
    {
        // logic
    }
};

The alternative is to put the common code into a function and call that from both constructors.

Upvotes: 4

Related Questions