Reputation: 878
If I try to save an int
and a std::thread
in an std::unordered_map<int, std::thread>
everything seems to work fine.
But if I wrap the std::unordered_map
, then I get an error in the standard library.
The error is: no matching constructor for initialization of '_Mypair'
Is there a way to get around this and make it work when it is wrapped?
This works:
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;
}
This doesn't work:
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;
}
This generates the error:
||=== 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)) ===|
Upvotes: 2
Views: 384
Reputation: 170104
You are accepting the value type by value already. Since the function parameter is local, you may move it (and may as well move the key too)
void add(KeyType key, valueType value)
{
mapper.emplace(std::move(key), std::move(value));
}
There's also no need to use std::make_pair
to emplace into the map.
If you want to be a bit more sophisticated, you may add some perfect forwarding support to add
, so as to avoid creating superfluous intermediate objects.
template<typename... Args>
void add(Args&&... args)
{
mapper.emplace(std::forward<Args>(args)...);
}
Upvotes: 5