使用“unique_ptr”创建“map”

Zio*_*yte 0 c++ dictionary unique-ptr

我最初在创建类时遇到问题map,在一些帮助下我意识到我实际上需要一个map<string, unique_ptr<myclass>>.

更准确地说:

  • 我有很多具有共同祖先的专门课程。
  • 专门化的类实际上是从同一个模板专门化的。
  • 我拥有std::map<std::string, unique_ptr<ancestor>>我的实例的所有权(我希望如此)。
  • 我需要所有权,因为创建实例的函数与使用它们的地方位于完全不同的代码部分。
  • 如果有用:我在初始化时创建map,然后仅在运行时引用它;出于所有实际目的,初始化它后(这是一个复杂的事情,涉及读取配置文件),它可能会变成 const.

我需要实现的一个最小的例子是:

#include <iostream>
#include <string>
#include <memory>
#include <map>

class generic {
    std::string _name;

public:
    generic(std::string name) : _name(name) {}
    virtual ~generic() = default;

    virtual std::string name() { return _name; }
    virtual std::string value() { return "no value in generic"; }
};

template <class T> class special : public generic {
    T _value;
public:
    special(std::string name, T value) : generic(name), _value(value) {}
    virtual ~special() = default;

    std::string value() override { return std::to_string(_value); }
};

template <typename T> void add_item(std::map <std::string, std::unique_ptr<generic>> &m, const std::string &n, const T &v) {
    m[n] = std::make_unique<special<T>>(typeid(v).name(), v);
}

int
main() {
    std::map <std::string, std::unique_ptr<generic>> instances;

    add_item<int>(instances, "int", 1);
    add_item<bool>(instances, "bool", true);
    add_item<float>(instances, "float", 3.1415);

    for (auto i : instances) {
        std::cout << i.first << " -- " << i.second.get()->name() << " -- " << i.second.get()->value() << std::endl;
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,我似乎遗漏了一些东西,因为编译炸弹“错误:使用已删除的函数”。

有好心人能帮我解决这个问题吗?

Ted*_*gmo 7

在此循环中,您尝试复制unique_ptrs,但unique_ptr复制构造函数被删除。

for (auto i : instances) {
Run Code Online (Sandbox Code Playgroud)

您需要通过引用来代替它们:

for (auto& i : instances) {
Run Code Online (Sandbox Code Playgroud)