如何将 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;
}
回到你的问题;
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));
考虑以下代码:
#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;
}
回到你的问题;
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));