使用 std::map 或 std::shared_ptr 调用 const 重载函数
call const overloaded function with std::map of std::shared_ptr
我正在尝试调用 const 重载函数
void process(std::map<std::string,std::shared_ptr<const Data_Struct>>);
使用我生成的数据。因为我生成数据,所以我使用了非常量版本
std::map<std::string,std::shared_ptr<Data_Struct>> my_data;
当我尝试使用
调用我的函数时
process(my_data);
我收到错误:
error C2664: 'void process(std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>)' : cannot convert argument 1 from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
我尝试了多种铸造变体,但都无法完成工作。感谢任何帮助。
这是我的测试代码,其中包含转换变体和相关的错误代码(我使用的是 Visual C++ 社区版 2013):
struct Data_Struct
{
int a;
std::string b;
};
void process(std::map<std::string,std::shared_ptr<const Data_Struct>>);
void calling_function() {
std::map<std::string,std::shared_ptr<Data_Struct>> my_data;
my_data.emplace("test",std::shared_ptr<Data_Struct>(new Data_Struct)).first->second->a = 2;
process(my_data);
// error C2664: 'void process(std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>)' : cannot convert argument 1 from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(std::map<std::string,std::shared_ptr<const Data_Struct>>(my_data));
// error C2440: '<function-style-cast>' : cannot convert from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process((std::map<std::string,std::shared_ptr<const Data_Struct>>)my_data);
// error C2440: 'type cast' : cannot convert from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(static_cast<std::map<std::string,std::shared_ptr<const Data_Struct>>>(my_data));
// error C2440: 'static_cast' : cannot convert from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(reinterpret_cast<std::map<std::string,std::shared_ptr<const Data_Struct>>>(my_data));
// error C2440: 'reinterpret_cast' : cannot convert from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(const_cast<std::map<std::string,std::shared_ptr<const Data_Struct>>>(my_data));
// error C2440: 'const_cast' : cannot convert from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(std::static_pointer_cast<std::map<std::string,std::shared_ptr<const Data_Struct>>>(my_data));
// error C2784: 'std::shared_ptr<_Ty> std::static_pointer_cast(const std::shared_ptr<_Ty2> &) throw()' : could not deduce template argument for 'const std::shared_ptr<_Ty2> &' from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(std::const_pointer_cast<std::map<std::string,std::shared_ptr<const Data_Struct>>>(my_data));
// error C2784: 'std::shared_ptr<_Ty> std::const_pointer_cast(const std::shared_ptr<_Ty2> &) throw()' : could not deduce template argument for 'const std::shared_ptr<_Ty2> &' from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
}
void process(std::map<std::string,std::shared_ptr<const Data_Struct>> data) {
for(auto &d : data)
std::cout << d.first << std::endl;
}
这两种地图类型完全无关,尽管表面上相似,但不能互换使用。不过,您确实有几个选择:
- 在其构造函数中填充您的数据class,这样您就不必在创建后更改它。
- 让流程函数在模板化迭代器范围而不是特定容器上工作。
- 让流程函数在模板化容器而不是特定类型上工作。
函数process()
按值获取参数。这意味着当它被调用时,地图的副本被获取、处理然后丢弃。我不知道这是不是你的意图。假设是,你需要的是一个转换函数:
#include <iostream>
#include <string>
#include <map>
#include <memory>
struct Data_Struct
{
int a;
std::string b;
};
void process(std::map<std::string,std::shared_ptr<const Data_Struct>>);
std::map<std::string,std::shared_ptr<const Data_Struct>>
convert_map(const std::map<std::string,std::shared_ptr<Data_Struct>>& source)
{
std::map<std::string,std::shared_ptr<const Data_Struct>> ret;
for(const auto& item : source) {
ret.emplace(item.first, item.second);
}
return ret;
}
void process(std::map<std::string,std::shared_ptr<const Data_Struct>> data) {
for(auto &d : data)
std::cout << d.first << std::endl;
}
void calling_function() {
std::map<std::string,std::shared_ptr<Data_Struct>> my_data;
my_data.emplace("test",std::shared_ptr<Data_Struct>(new Data_Struct)).first->second->a = 2;
process(convert_map(my_data));
}
using namespace std;
int main()
{
calling_function();
return 0;
}
我正在尝试调用 const 重载函数
void process(std::map<std::string,std::shared_ptr<const Data_Struct>>);
使用我生成的数据。因为我生成数据,所以我使用了非常量版本
std::map<std::string,std::shared_ptr<Data_Struct>> my_data;
当我尝试使用
调用我的函数时process(my_data);
我收到错误:
error C2664: 'void process(std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>)' : cannot convert argument 1 from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
我尝试了多种铸造变体,但都无法完成工作。感谢任何帮助。
这是我的测试代码,其中包含转换变体和相关的错误代码(我使用的是 Visual C++ 社区版 2013):
struct Data_Struct
{
int a;
std::string b;
};
void process(std::map<std::string,std::shared_ptr<const Data_Struct>>);
void calling_function() {
std::map<std::string,std::shared_ptr<Data_Struct>> my_data;
my_data.emplace("test",std::shared_ptr<Data_Struct>(new Data_Struct)).first->second->a = 2;
process(my_data);
// error C2664: 'void process(std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>)' : cannot convert argument 1 from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(std::map<std::string,std::shared_ptr<const Data_Struct>>(my_data));
// error C2440: '<function-style-cast>' : cannot convert from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process((std::map<std::string,std::shared_ptr<const Data_Struct>>)my_data);
// error C2440: 'type cast' : cannot convert from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(static_cast<std::map<std::string,std::shared_ptr<const Data_Struct>>>(my_data));
// error C2440: 'static_cast' : cannot convert from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(reinterpret_cast<std::map<std::string,std::shared_ptr<const Data_Struct>>>(my_data));
// error C2440: 'reinterpret_cast' : cannot convert from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(const_cast<std::map<std::string,std::shared_ptr<const Data_Struct>>>(my_data));
// error C2440: 'const_cast' : cannot convert from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' to 'std::map<std::string,std::shared_ptr<const Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(std::static_pointer_cast<std::map<std::string,std::shared_ptr<const Data_Struct>>>(my_data));
// error C2784: 'std::shared_ptr<_Ty> std::static_pointer_cast(const std::shared_ptr<_Ty2> &) throw()' : could not deduce template argument for 'const std::shared_ptr<_Ty2> &' from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
process(std::const_pointer_cast<std::map<std::string,std::shared_ptr<const Data_Struct>>>(my_data));
// error C2784: 'std::shared_ptr<_Ty> std::const_pointer_cast(const std::shared_ptr<_Ty2> &) throw()' : could not deduce template argument for 'const std::shared_ptr<_Ty2> &' from 'std::map<std::string,std::shared_ptr<Data_Struct>,std::less<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>'
}
void process(std::map<std::string,std::shared_ptr<const Data_Struct>> data) {
for(auto &d : data)
std::cout << d.first << std::endl;
}
这两种地图类型完全无关,尽管表面上相似,但不能互换使用。不过,您确实有几个选择:
- 在其构造函数中填充您的数据class,这样您就不必在创建后更改它。
- 让流程函数在模板化迭代器范围而不是特定容器上工作。
- 让流程函数在模板化容器而不是特定类型上工作。
函数process()
按值获取参数。这意味着当它被调用时,地图的副本被获取、处理然后丢弃。我不知道这是不是你的意图。假设是,你需要的是一个转换函数:
#include <iostream>
#include <string>
#include <map>
#include <memory>
struct Data_Struct
{
int a;
std::string b;
};
void process(std::map<std::string,std::shared_ptr<const Data_Struct>>);
std::map<std::string,std::shared_ptr<const Data_Struct>>
convert_map(const std::map<std::string,std::shared_ptr<Data_Struct>>& source)
{
std::map<std::string,std::shared_ptr<const Data_Struct>> ret;
for(const auto& item : source) {
ret.emplace(item.first, item.second);
}
return ret;
}
void process(std::map<std::string,std::shared_ptr<const Data_Struct>> data) {
for(auto &d : data)
std::cout << d.first << std::endl;
}
void calling_function() {
std::map<std::string,std::shared_ptr<Data_Struct>> my_data;
my_data.emplace("test",std::shared_ptr<Data_Struct>(new Data_Struct)).first->second->a = 2;
process(convert_map(my_data));
}
using namespace std;
int main()
{
calling_function();
return 0;
}