由于派生自 std::map [closed] 的类中的 std::map 迭代器导致内存错误

Memory error due to std::map iterator in a class derived from std::map [closed]

提问人:Ninrich 提问时间:6/7/2019 更新时间:6/7/2019 访问量:235

问:


编辑问题以包括所需的行为、特定问题或错误以及重现问题所需的最短代码。这将有助于其他人回答这个问题。

4年前关闭。

我正在从 std::map 派生一个类,因为我希望为此数据结构创建自己的方法。我在使用“mySelect”时遇到了问题,如果元素不存在,它应该返回nullptr,否则unique_ptr。

我尝试在迭代器声明之前指定 typename 关键字,但无济于事。

template <class KeyType, class ValueType>
class Container : public std::map<KeyType, ValueType> {

    public:
        std::unique_ptr<ValueType> mySelect(KeyType key) {
        typename map<KeyType, ValueType>::iterator value;
            if ((value = this->find(key)) == this->end())
            return nullptr;
        return std::make_unique<ValueType>(value);
        }
}

我收到此错误:

Error   C2664   'std::vector<std::shared_ptr<Transaction>,std::allocator<_Ty>>::vector(const std::vector<_Ty,std::allocator<_Ty>> &)': cannot convert argument 1 from 'std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>' to 'const _Alloc &'
C++ 字典 模板 std

评论

0赞 Slava 6/7/2019
这应该做什么?std::make_unique<ValueType>(value)
1赞 Yksisarvinen 6/7/2019
不是您的问题,但值得一读:从 C++ STL 容器派生是否有任何真正的风险?
0赞 Ninrich 6/7/2019
它应该返回一个unique_ptr,指向迭代器找到的 Value 类型的值。
1赞 L. F. 6/7/2019
你能提供一个最小的可重复的例子吗?显示您的使用方式。Container
0赞 Slava 6/7/2019
那么你就完全走错了路。1 - 创建一个新实例。2 - 提供所有权。3 - 您尝试创建一个新实例并从迭代器初始化它std::make_uniquestd::unique_ptr

答:

0赞 Slava 6/7/2019 #1

首先是这段代码:

 return std::make_unique<ValueType>(value);

在逻辑上等于:

std::unique_ptr<ValueType> tmp = new Value(value);
return tmp;

(虽然它不一样,所以你不应该用另一个代替一个,只是为了让你理解)。因此,您正在尝试创建一个新的类实例并从迭代器初始化它。除非提供这样的构造函数,否则这将不起作用。如果您想制作副本并在转让所有权时将其归还,请将您的代码更改为:ValueValue

 return std::make_unique<ValueType>(value->second);

但我不确定这是你想做的。如果要返回指向现有对象的指针,则不能在此处使用,因为它提供了唯一的所有权(例如名称),您需要按值存储在映射而不是对象中并返回它的副本,或者只是返回原始指针。std::unique_ptrstd::shared_ptr

如何使 mySelect() 的调用方成为返回对象的所有者?

正如我所说,您存储对象并与此方法的调用者共享所有权,或者您最初将对象存储为,但随后您必须将其移出,因为您将无法再拥有该对象。std::shared_ptrstd::unique_ptrstd::map