Proper way of transferring ownership of a std::vector< std> > to a class being constructed

后端 未结 1 929
情话喂你
情话喂你 2021-02-03 22:52

What is the proper way of transferring ownership of a std::vector > to a class being constructed?

Below is a code representation

相关标签:
1条回答
  • 2021-02-03 23:29

    std::unique_ptr<T> is a non-copyable but movable type. Having a move-only type in a std:vector<T> make the std::vector<T> move-only, too. To have the compiler automatically move objects, you need to have an r-value for move-construction or move-assignment. Within your constructor the object vecOfIntPtrsOwnedByCaller is an l-value, although one which, despite its name, already owns the pointed to ints: they got "stolen" from the caller when the caller created the object. To move from an l-value, you need to use std::move() (or something equivalent):

    Foo::Foo(std::vector<std::unique_ptr<int>> vecOfIntPtrsOwnedByCaller)
    {
        _vecOfIntPtrsOwnedByFoo = std::move(vecOfIntPtrsOwnedByCaller);
    }
    

    or, preferable

    Foo::Foo(std::vector<std::unique_ptr<int>> vecOfIntPtrsOwnedByCaller)
        : _vecOfIntPtrsOwnedByFoo(std::move(vecOfIntPtrsOwnedByCaller))
    {
    }
    

    The latter approach avoid first default-constructing the member and then move-assigning to it and, instead, move-constructs the member directly. I guess, I would also make the argument an r-value reference but this isn't necessary.

    Note, that you can construct objects of type Foo only from something which can be bound to an r-value, e.g.:

    int main() {
        Foo f0(std::vector<std::unique_ptr<int>>()); // OK
        std::vector<std::unique_ptr<int>> v;
        Foo f1(v); v// ERROR: using with an l-value
        Foo f2{v}; v// ERROR: using with an l-value
        Foo f3 = v; // ERROR: using with an l-value
        Foo f4(std::move(v)); // OK: pretend that v is an r-value
    }
    
    0 讨论(0)
提交回复
热议问题