I stumbled across a behaviour of std::make_pair that I do not understand. Given the following code
#include <iostream>
using namespace std;
#include <memory>
#include <utility>
class TestClass
{
public:
TestClass(const std::string& str) : str{std::make_unique<const std::string>(str)} {};
~TestClass() = default; // (1)
private:
std::unique_ptr<const std::string> str{}; // (2)
// const std::unique_ptr<const std::string> str{}; // (3)
};
int main()
{
// is fine all the time
TestClass myTestClass = TestClass("myTestClass"); // (4)
// doesn't work at all
std::make_pair("myTestClassKey", myTestClass); // (5)
// works, but only wit (1) commented out and (2) instead of (3)
std::make_pair("myTestClassKey", TestClass("myTestClass")); // (6)
return 0;
}
Lines (1) to (3) in TestClass
are causing me a headache. While line (4) works regardless of line (1) and (2) OR (3) uncommented, line (5) does not work at all and line (6) only compiles if line (1) is commented out and line (2) is used instead of line (3). The compiler error I receive is always something like:
||=== Build: Debug in test (compiler: GNU GCC Compiler) ===|
/usr/include/c++/9/bits/stl_pair.h||In instantiation of ‘constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&) [with _T1 = const char (&)[15]; _T2 = TestClass; typename std::__decay_and_strip<_T2>::__type = TestClass; typename std::__decay_and_strip<_Tp>::__type = const char*]’:|
/home/johndoe/Coding/test/main.cpp|26|required from here|
/usr/include/c++/9/bits/stl_pair.h|529|error: no matching function for call to ‘std::pair<const char*, TestClass>::pair(const char [15], TestClass)’|
/usr/include/c++/9/bits/stl_pair.h|436|note: candidate: ‘template<class ... _Args1, long unsigned int ..._Indexes1, class ... _Args2, long unsigned int ..._Indexes2> std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>)’|
/usr/include/c++/9/bits/stl_pair.h|436|note: template argument deduction/substitution failed:|
/usr/include/c++/9/bits/stl_pair.h|529|note: mismatched types ‘std::tuple<_Tps ...>’ and ‘const char [15]’|
/usr/include/c++/9/bits/stl_pair.h|375|note: candidate: ‘template<class ... _Args1, class ... _Args2> std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>)’|
...
/usr/include/c++/9/bits/stl_pair.h|529|note: candidate expects 0 arguments, 2 provided|
||=== Build failed: 9 error(s), 2 warning(s) (0 minute(s), 0 second(s)) ===|
In short, why's that? My only idea so far is that it could be related to move / copy construction of the std::unique_ptr? But why would line (1) cause trouble then?