Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;:避免",;删除功能的使用“;错误_C++_Multithreading_Queue - Fatal编程技术网

C++ C++;:避免",;删除功能的使用“;错误

C++ C++;:避免",;删除功能的使用“;错误,c++,multithreading,queue,C++,Multithreading,Queue,我已经编写了一个小类,它实现了一个特殊的线程安全队列,该队列在最后一次写入该队列几秒钟后将自身备份到数据库中(因此,如果在此之前读取了队列,则数据库将不受影响) 我需要几个这样的队列,在某一点上我需要访问所有队列,所以我想把它们放到std::map中,这样我就可以通过它的键访问单个队列,并使用迭代器访问所有队列。 不幸的是,我在尝试插入一对密钥和相应的队列对象时出现了“使用已删除函数”错误。在查找含义时,我意识到问题可能是我使用了std::mutex来确保队列线程安全(在我的用例中这是一个绝对重

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

我需要几个这样的队列,在某一点上我需要访问所有队列,所以我想把它们放到
std::map
中,这样我就可以通过它的键访问单个队列,并使用迭代器访问所有队列。 不幸的是,我在尝试插入一对密钥和相应的队列对象时出现了“使用已删除函数”错误。在查找含义时,我意识到问题可能是我使用了
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;
};
类队列数据
{
公众:
QueueData(std::string表);
长GetLastSync(void);
void PushRecord(const std::string和msg);
std::字符串PopRecord(void);
void PopulateQueue(void);
无效转储队列(void);
无效清除(无效);
大小\u t获取大小(无效);
私人:
std::字符串_表;
std::deque_队列;
长时间同步;
std::mutex\umxqueue;
};

您不能移动/复制
std::mutex
,因此也不能移动/复制
QueueData
。相反,您必须就地构造它,这是通过
emplace()
成员完成的(自C++11以来的大多数STL容器都支持)

std::map QueueMap;
QueueMap.emplace(std::分段_构造,
标准::转发作为元组(键),
std::forward_as_tuple(table));
//使用C++17,您可以
QueueMap.try_emplace(键,表);//C++17

欢迎来到堆栈溢出。请花点时间阅读并参考您可以在此处询问的内容和方式。好的,避免该错误的最佳方法是不使用已删除的函数。(提示:)我知道互斥体是不可复制的,事实上我已经把它写进了我的问题中。不幸的是,我绝对无法避免使用互斥。请删除自动生成的复制构造函数和赋值运算符。或者你的意思是你的课可以被复制?但是。。。您不需要一个互斥体的副本,只需编写复制构造函数并初始化一个新的互斥体。如果互斥锁已锁定,则引发异常。另外,把你的标题改成能更好地反映你想要的内容的标题,并格式化巨大的文字墙
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