如何将 const std::shared_ptr 插入 std::map

How to insert a const std::shared_ptr into a std::map

考虑以下代码:

#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;
}

你必须编译它:g++ -std=c++11 <filename>.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));

从我读到的错误来看,编译器在我尝试插入地图时需要一个 r 值。为什么?我在这里犯了什么错误?

请注意,我是根据大型代码库中的一些现有代码创建此代码段的。可能还值得一提的是,该片段取自 Windows 上 运行 的代码库,我的任务是将其移植到 Linux。原作者曾使用std::tr1::shared_ptr。我将其修改为使用 std::shared_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;
}

参见:http://ideone.com/4AQfqd

回到你的问题;

testO.cpp:14:83: note: cannot convert ‘vp_int8’ (type ‘ConstDataTypePtr {aka std::shared_ptr >}’) to type ‘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 模板提供了错误的类型。只是改变

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

进入

m_nameToType.insert(std::make_pair<std::string, ConstDataTypePtr>(std::string("int8_t"), vp_int8));

(注意 std::make_pair<std::string, ConstDataTypePtr> 部分)

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

std::make_pair 的重点是让编译器推导类型。如果要提供类型,请使用 std::pair<K, V>

所以

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);

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

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