当 std::unordered_map 包装在一个类中时,它不接受 std::thread
Posted
技术标签:
【中文标题】当 std::unordered_map 包装在一个类中时,它不接受 std::thread【英文标题】:std::unordered_map doesn't accept std::thread when it is wrapped in a class 【发布时间】:2018-01-03 20:39:57 【问题描述】:如果我尝试将int
和std::thread
保存在std::unordered_map<int, std::thread>
中,一切似乎都正常。
但是如果我包装std::unordered_map
,那么我会在标准库中得到一个错误。
错误是:no matching constructor for initialization of '_Mypair'
有没有办法解决这个问题并使其在包装后工作?
这行得通:
Source.cpp
#include <thread>
#include <unordered_map>
void display()
int main()
std::unordered_map<int, std::thread> map_;
std::thread tempThread(&display);
map_.emplace(0, std::move(tempThread));
return 0;
这不起作用:
MapperWrapper.h
#ifndef MAPPERWRAPPER_H
#define MAPPERWRAPPER_H
#include <unordered_map>
#include <utility>
template <typename KeyType, typename valueType> class MapperWrapper
public:
void add(KeyType key, valueType value)
mapper.emplace(std::make_pair(key, value));
protected:
std::unordered_map<KeyType, valueType> mapper;
;
#endif // MAPPERWRAPPER_H
Source.cpp
#include <thread>
#include "MapperWrapper.h"
void display()
int main()
MapperWrapper<int, std::thread> map_;
std::thread tempThread(&display);
map_.add(0, std::move(tempThread));
return 0;
这会产生错误:
||=== Build: Debug in Testing (compiler: LLVM Clang Compiler) ===|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|327|error: no matching constructor for initialization of '_Mypair' (aka 'pair<int, std::thread>')|
C:\Users\usr\Desktop\Project2\Project2\MapperWrapper.h|12|in instantiation of function template specialization 'std::make_pair<int &, std::thread &>' requested here|
C:\Users\usr\Desktop\Project2\Project2\Source.cpp|12|in instantiation of member function 'MapperWrapper<int, std::thread>::add' requested here|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|96|note: candidate template ignored: requirement 'is_copy_constructible<thread>::value' was not satisfied [with _Uty1 = int, _Uty2 = std::thread]|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|107|note: candidate template ignored: requirement 'is_copy_constructible<thread>::value' was not satisfied [with _Uty1 = int, _Uty2 = std::thread]|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|167|note: candidate template ignored: requirement 'is_constructible<thread, thread &>::value' was not satisfied [with _Other1 = int &, _Other2 = std::thread &]|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|181|note: candidate template ignored: requirement 'is_constructible<thread, thread &>::value' was not satisfied [with _Other1 = int &, _Other2 = std::thread &]|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|85|note: candidate constructor template not viable: requires 0 arguments, but 2 were provided|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|121|note: candidate constructor template not viable: requires single argument '_Right', but 2 arguments were provided|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|132|note: candidate constructor template not viable: requires single argument '_Right', but 2 arguments were provided|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|150|note: candidate constructor template not viable: requires 4 arguments, but 2 were provided|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|157|note: candidate constructor template not viable: requires 3 arguments, but 2 were provided|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|195|note: candidate constructor template not viable: requires single argument '_Right', but 2 arguments were provided|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|209|note: candidate constructor template not viable: requires single argument '_Right', but 2 arguments were provided|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|112|note: candidate constructor not viable: requires 1 argument, but 2 were provided|
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\utility|113|note: candidate constructor not viable: requires 1 argument, but 2 were provided|
||=== Build failed: 1 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
【问题讨论】:
【参考方案1】:您已经按值接受值类型。由于函数参数是本地的,你可以移动它(也可以移动键)
void add(KeyType key, valueType value)
mapper.emplace(std::move(key), std::move(value));
也无需使用std::make_pair
置入地图。
如果你想更精致一点,可以给add
添加一些完善的转发支持,避免创建多余的中间对象。
template<typename... Args>
void add(Args&&... args)
mapper.emplace(std::forward<Args>(args)...);
【讨论】:
签名读取void add(KeyType&& key, valueType&& value)
会有什么好处/坏处吗?
@Questionable - 除了强制所有类型的调用方移动之外,没有。如果你想添加完美转发,我更新了我的答案。以上是关于当 std::unordered_map 包装在一个类中时,它不接受 std::thread的主要内容,如果未能解决你的问题,请参考以下文章
如何以线程安全的方式使用`std::unordered_map`?
std::vector 或 std::list 用于 std::unordered_map 存储桶?
std::unordered_map 不断导致错误,这是一个错误吗?