使用unique_ptr将对象推入C++中的向量

Stu*_*acy 7 c++ smart-pointers vector move-semantics c++11

我有一个简单的类结构建模离散模拟,带有状态向量,每个状态包含许多过渡,作为智能指针的向量.我已经使用智能指针来保存转换,就像在我的完整应用程序中我需要多态性一样.

#include <vector>
#include <memory>

class Transition {
    public:
        Transition() {}
};


class State {
    public:
        State(int num) : num(num), transitions() {}
        void add_transition(std::unique_ptr<Transition> trans) {
            transitions.push_back(std::move(trans));
        }

    private:
        int num;
        std::vector<std::unique_ptr<Transition>> transitions;
};


int main() {
    std::vector<State> states;
    for (int i = 0; i < 10; i++) {
        State nstate = State(i);
        for (int j = 0; j < 2; j++) {
            nstate.add_transition(std::move(std::unique_ptr<Transition>(new Transition())));
        }
        // This line causes compiler errors
        states.push_back(nstate);
    }
}
Run Code Online (Sandbox Code Playgroud)

将新状态对象添加到向量时,我遇到编译器错误:

Error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = Transition; _Dp = std::default_delete<Transition>]’
 { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
Run Code Online (Sandbox Code Playgroud)

我想这是由于vector制作了State对象的副本,它也试图制作一个unique_ptrs不允许的向量的副本.我已经看到它emplace_back不会像push_back我那样复制,但我仍然得到同样的错误.

将State对象直接添加到向量中是有效的,但我更愿意避免这种解决方法,因为在我的实际代码中我更多地使用State对象而不是仅仅添加转换而不想继续访问向量.

int main() {
    std::vector<State> states;
    for (int i = 0; i < 10; i++) {
        states.push_back(State(i));
        for (int j = 0; j < 2; j++) {
            states[i].add_transition(std::move(std::unique_ptr<Transition>(new Transition())));
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

son*_*yao 7

State不可复制,只能移动;但是,对于states.push_back(nstate);nstate是一个左值(作为命名的变量),其不能从移动。然后尝试执行副本,但不允许。

要解决它,您可以使用std::move(将其转换为右值):

states.push_back(std::move(nstate));
Run Code Online (Sandbox Code Playgroud)

居住


请注意,在移动操作之后,nstate(包括向量及其内容)的数据成员也将被移动。