C ++:避免​​“使用已删除的函数”错误

时间:2017-05-23 10:27:29

标签: c++ multithreading queue

我编写了一个小类,它实现了一个特殊的线程安全队列,在最后一次写入此队列后几秒钟将自身备份到数据库中(因此,如果在此之前读取队列,则数据库将保持不变)

我需要其中几个队列,但有一次我需要访问它们,所以我想把它们放到std::map中,这样我就可以通过它的密钥访问一个队列,所有这些都是迭代器。 不幸的是,当尝试insert()一对密钥和相应的队列对象时,我得到了“使用已删除的函数”错误。在查找含义时,我意识到问题可能是我使用std::mutex来使队列成为线程安全的(在我的用例中是一个绝对重要的要求)而且std::mutex显然是不可移动的不可复制。

所以我的问题是:如何将该类的多个实例放入std::map?我的意思是,没有真正的需要复制任何东西,我不会在开始填充一次后调整地图大小,我不会从中删除任何对象,地图从应用程序的开始有生命时间,直到机器重新启动。地图本身被声明为静态,我不会制作此地图的任何副本,我只想以一种舒适的方式访问队列,效率是一个非问题,只有代码可读性。

这是队列类的样子:

class QueueData
{
    public:
        QueueData(std::string table);
        long GetLastSync(void);
        void PushRecord(const std::string& msg);
        std::string PopRecord(void);
        void PopulateQueue(void);
        void DumpQueue(void);
        void Clear(void);
        size_t GetSize(void);
    private:
        std::string _table;
        std::deque<std::string> _queue;
        long _lastSync;
        std::mutex _mxqueue;
};

1 个答案:

答案 0 :(得分:1)

您无法移动/复制std::mutex,因此也无法移动/复制QueueData。相反,您必须在适当的位置构建它,这是通过emplace()成员完成的(自C ++ 11以来大多数STL容器都支持)。

std::map<key_type, QueueData> QueueMap;

QueueMap.emplace(std::piecewise_construct,
                 std::forward_as_tuple(key),
                 std::forward_as_tuple(table));

// with C++17, you can
QueueMap.try_emplace(key,table);   // C++17