Shokwav
Shokwav

Reputation: 664

Proper Use of Move Semantics in This Situation?

Sorry if the title is a bit vague; I will try to clarify it thru some examples. Suppose I have a class Foo, which contains an init method:

class Foo{
    auto init(const BigMemoryHungryType& t) -> void {
        //do a ton of stuff
    }
};

Now suppose that I would like to create an overload of this init method, this time accepting an rvalue of type BigMemoryHungryType, so that I can simply perform move semantics:

class Foo{
    auto init(const BigMemoryHungryType& t) -> void {
        //do a ton of stuff
    }

    auto init(BigMemoryHungryType&& t) -> void {
        //exact same as other init, but utilizing move semantics
    }

};

How could I keep the copy-paste to a minimum here? The method I'm thinking of involves assigning all the members in both init methods, then calling a protected/private init method to do the actual work:

class Foo{
    auto init(const BigMemoryHungryType& t) -> void {
        real_t = t;
        init();
    }

    auto init(BigMemoryHungryType&& t) -> void {
        real_t = std::move(t);
        init();
    }

private:
    auto init() -> void {
        //do actual work
    }

    BigMemoryHungryType real_t;
};

This seems fine and all, however it violates the strong exception guarantee if init() throws an exception. Am I missing something obvious here?

Upvotes: 1

Views: 85

Answers (1)

Bryan Chen
Bryan Chen

Reputation: 46598

try this

auto init(BigMemoryHungryType t) -> void {
   init(std::move(t));
}

it will copy BigMemoryHungryType once to temporary and move it to the instance field in the move overload

Upvotes: 3

Related Questions