C++ 如何将常量std::shared\u ptr插入std::map

C++ 如何将常量std::shared\u ptr插入std::map,c++,c++11,rvalue-reference,C++,C++11,Rvalue Reference,考虑以下代码: #include <string> #include <map> #include <memory> #include <utility> #include <iostream> typedef std::shared_ptr<const std::string> ConstDataTypePtr; typedef std::map<std::string, ConstDataTypePtr>

考虑以下代码:

#include <string>
#include <map>
#include <memory>
#include <utility>
#include <iostream>

typedef std::shared_ptr<const std::string> ConstDataTypePtr;
typedef std::map<std::string, ConstDataTypePtr> StrDataTypeMap;

int main()
{
    StrDataTypeMap m_nameToType;
    ConstDataTypePtr vp_int8(new std::string("RGH"));
    m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>("int8_t", vp_int8));
    return 0;
}
#包括
#包括
#包括
#包括
#包括
typedef std::shared_ptr ConstDataTypePtr;
typedef std::map StrDataTypeMap;
int main()
{
标准数据类型映射m_nameToType;
ConstDataTypePtr vp_int8(新标准::字符串(“RGH”);
m_nameToType.insert(std::make_pair(“int8_t”,vp_int8));
返回0;
}
您必须使用以下命令编译它:
g++-std=c++11.cpp

它给出了以下错误:

    testO.cpp: In function ‘int main()’:
testO.cpp:14:88: error: no matching function for call to ‘make_pair(const char [7], ConstDataTypePtr&)’
     m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>("int8_t", vp_int8));
                                                                                        ^
testO.cpp:14:88: note: candidate is:
In file included from /usr/include/c++/4.8.2/bits/stl_algobase.h:64:0,
                 from /usr/include/c++/4.8.2/bits/char_traits.h:39,
                 from /usr/include/c++/4.8.2/string:40,
                 from testO.cpp:1:
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5: note: template<class _T1, class _T2> constexpr std::pair<typename std::__decay_and_strip<_Tp>::__type, typename std::__decay_and_strip<_T2>::__type> std::make_pair(_T1&&, _T2&&)
     make_pair(_T1&& __x, _T2&& __y)
     ^
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5: note:   template argument deduction/substitution failed:
testO.cpp:14:88: note:   cannot convert ‘vp_int8’ (type ‘ConstDataTypePtr {aka std::shared_ptr<const std::basic_string<char> >}’) to type ‘std::shared_ptr<const std::basic_string<char> >&&’
     m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>("int8_t", vp_int8));
testO.cpp:在函数“int main()”中:
testO.cpp:14:88:错误:调用“make_pair(const char[7],ConstDataTypePtr&)”时没有匹配函数
m_nameToType.insert(std::make_pair(“int8_t”,vp_int8));
^
testO.cpp:14:88:注:候选人为:
在/usr/include/c++/4.8.2/bits/stl_algobase.h:64:0中包含的文件中,
从/usr/include/c++/4.8.2/bits/char_traits.h:39,
从/usr/include/c++/4.8.2/string:40,
来自testO.cpp:1:
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5:注:模板constepr std::pair std::make_pair(_T1&,_T2&)
配对(T1和x、T2和y)
^
/usr/include/c++/4.8.2/bits/stl_pair.h:276:5:注意:模板参数推导/替换失败:
testO.cpp:14:88:注意:无法将“vp_int8”(类型“ConstDataTypePtr{aka std::shared_ptr}”)转换为类型“std::shared_ptr&”
m_nameToType.insert(std::make_pair(“int8_t”,vp_int8));
从我读到的错误来看,当我试图插入到映射中时,编译器期望一个r值。为什么?我在这里犯了什么错误

请注意,我从一些现有代码创建了这个代码段,这些代码是大型代码库的一部分。可能还值得一提的是,该代码段取自在Windows上运行的代码库,我的任务是将其移植到Linux。最初的作者使用了std::tr1::shared\u ptr。我将其修改为使用std::shared\u ptr。我没想到这一变化会带来任何影响

#包括
#include <memory>
#include <map>
#include <string>

int main() {
    using shared_data = std::shared_ptr<const std::string>;

    std::map<std::string, shared_data> map;
    map.insert(std::make_pair(
        "something", 
        shared_data(new std::string("something else"))
    ));
    return 0;
}
#包括 #包括 int main(){ 使用shared_data=std::shared_ptr; 地图; map.insert(std::make_pair)( “某物”, 共享_数据(新std::string(“其他内容”)) )); 返回0; }
见:

回到你的问题上来

testO.cpp:14:83:注意:无法将'vp_int8'(类型'ConstDataTypePtr{aka std::shared_ptr>})转换为'std::basic_string&' m_nameToType.insert(std::make_pair(“int8_t”,vp_int8))

你所拥有的:

std::make_pair<std::string, std::string>(some_string, TOTALLY_NOT_A_STRING)
std::make_pair(一些字符串,完全不是字符串)

您为std::make\u pair模板提供了错误的类型。换衣服

m_nameToType.insert(std::make_pair<std::string, std::string>("int8_t", vp_int8));
m_nameToType.insert(std::make_pair(“int8_t”,vp_int8));
进入

m_nameToType.insert(std::make_pair(std::string(“int8_t”),vp_int8));
(注意
std::make_pair
部分)


编辑:或者根本不提供模板参数,正如有人在评论中建议的那样。

std::make_pair的全部要点是让编译器推断类型。如果要提供类型,请使用
std::pair

所以


不要在make_pair函数中提及模板中的类型

m_nameToType.insert(std::make_pair("int8_t", vp_int8));

std::make_pair
的全部要点是让编译器推断类型。如果您想提供类型,请使用
std::pair
。以后,请发布实际重现您遇到的确切问题的。在别人为您的问题提供解决方案之后编辑您的问题,并将其更改为新问题,这是一种糟糕的形式。在编辑之前,@PatrykWertka成功地解决了您的问题,但您继续编辑您的问题,产生了一个不同的问题,PatrykWertka的解决方案仍然解决了这个问题。您好,非常抱歉,我之前的代码中出现了这个错误。然而,仍然存在一个问题。你能再看一下吗?我已经更新了代码和错误。你是对的。删除模板参数将删除错误。但是,您能告诉我在这种情况下正确的模板参数是什么吗?我的回答中包括了它—“是正确的模板参数。实际上,不是;使用
不起作用。如果你再看一次我的问题(我在看到你的答案后更新了这个问题),你会注意到我现在正在使用
。我仍然得到我提到的错误。你是对的。早些时候我用错了类型。请你再看一遍这个问题好吗?(我已经更新了)。我仍然得到了一个错误。
std::make_pair
应该有一个默认的第一个模板类型参数,名为
class stop\u将参数传递给\u me=I\u am\u not \u开玩笑
和一个
static\u断言(std::is\u same::value),“不要手动为std::make_pair提供类型参数。如果要这样做,请直接使用std::pair。您使用我是错误的。”)
但这可能太微妙了。@Yakk是的,讽刺在这里做得很好;但是更好的人可以解释为什么传递类型参数会产生这个确切的错误。@wild这可能是未指定的行为,但特定的错误是因为完美转发失败。通过将
X
作为类型传递,arg就是
X&&
,一个右值,您传递了一个左值。上面的注释是因为此
make\u-pair
错误非常常见。引入此错误可能是因为您猜测从仅复制到可移动的make\u-pair。
m_nameToType.insert(std::make_pair<std::string, std::string>("int8_t", vp_int8));
m_nameToType.insert(std::make_pair("int8_t", vp_int8));
m_nameToType.insert(std::pair<const std::string, ConstDataTypePtr>("int8_t", vp_int8));
m_nameToType.emplace("int8_t", vp_int8);
m_nameToType.insert(std::make_pair("int8_t", vp_int8));