通过不返回引用来防止下标操作符的赋值会导致运行时崩溃

时间:2014-07-04 18:40:18

标签: c++ templates operator-overloading

我这样做:

template<typename T> class var_accessor {
public:
    std::set<std::shared_ptr<T>> varset;
    std::map<std::string,std::shared_ptr<T>> vars_by_name;
    std::map<uint32,std::shared_ptr<T>> vars_by_id;
    std::shared_ptr<T> operator[](const uint32& index) { return vars_by_id[index]; }
    std::shared_ptr<T> operator[](const std::string& index) { return vars_by_name[index]; }

    bool is_in_set(std::shared_ptr<T> what) { auto it = varset.find(what); if (it == varset.end()) return false; return true; }
    bool is_in_set(uint32 what) { auto it = vars_by_id.find(what); if (it == vars_by_id.end()) return false; return true; }
    bool is_in_set(std::string& what) { auto it = vars_by_name.find(what); if (it == vars_by_name.end()) return false; return true; }

    bool place(std::shared_ptr<T> what, const uint32 whatid, const std::string& whatstring) {
        if (is_in_set(what)) return false;
        varset.emplace(what);
        vars_by_name.emplace(whatstring,what);
        vars_by_id.emplace(whatid,what);
        return true;
    }
};

则...

class whatever {
    std::string name;
    std::function<int32()> exec;
};

class foo {
  public:
    var_accessor<whatever> stuff;
};

这有效:

std::shared_ptr<whatever> thing(new whatever);
thing->name = "Anne";
thing->exec = []() { return 1; }

foo person;
person.stuff.emplace(thing, 1, thing->name);

让名字崩溃:

std::cout << person.stuff[1]->name;

但是如果我将operator []更改为返回引用,它就可以正常工作。

我不想在不添加所有3个结构的情况下意外添加新元素,这就是我制作的原因

std::shared_ptr<T> operator[]

而不是

std::shared_ptr<T>& operator[]

有没有办法阻止下标分配,但保留下标操作符?

要明确我希望能够继续这样做

std::cout << person.stuff[4];

但是无法做到

std::shared_ptr<whatever> bob(new whatever);
bob->name = "bob";
person.stuff[2] = bob;

错误是std :: string类疯狂内的EXC_BAD_ACCESS 我读到的所有内容都只是“如果你想阻止任务,就不要返回引用”,但它也阻止了我使用它。

是的我知道有些事情应该是私密的,但我只是想让它先工作。

在XCode 5.1中使用Clang / LLVM 谢谢!

1 个答案:

答案 0 :(得分:4)

您应该返回一个const引用。见this question

const引用意味着不允许调用者更改值,只能查看它。因此赋值将是编译时错误。但使用它会起作用(并且效率很高)。