如何正确将rapidjson::Object传递给C++类成员方法?
如何将rapidjson::Object传递给类成员方法?
问题代码
我编写了如下代码:
void CMyClass::SomeMethod() { rapidjson::Document doc; doc.Parse(data.c_str(), data.size()); std::string output{}; for (const auto& obj : doc.GetObj()) { if ("My_data" == obj.name) { ReadMyData(obj, output); continue; } } } void CMyClass::ReadMyData(???, std::string& output) { // 待实现逻辑 }
尝试的模板方法定义
我尝试使用如下模板方法定义:
头文件声明
template<bool Flag, typename T> void ReadMyData(const rapidjson::GenericObject<Flag, T>& obj, std::string& output);
实现部分
template<bool Flag, typename T> void CMyClass::ReadMyData(const rapidjson::GenericObject<Flag, T>& obj, SWeather& output) { }
编译错误
但出现了以下编译错误:
.cpp(109): error C2672: 'CMyClass::ReadMyData': no matching overloaded function found .cpp(109): error C2784: 'void CMyClass::ReadMyData(const rapidjson::GenericObject<Const,ValueT> &,std::string &)': could not deduce template argument for 'const rapidjson::GenericObject<Const,ValueT> &' from 'const rapidjson::GenericMember<Encoding,Allocator>' 1> with 1> [ 1> Encoding=rapidjson::UTF8<char>, 1> Allocator=rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator> 1> ]
补充信息
GetObj()的定义如下:
Object GetObj() { RAPIDJSON_ASSERT(IsObject()); return Object(*this); }
且Object是rapidjson命名空间中GenericValue类的类型定义:
template <typename Encoding, typename Allocator = RAPIDJSON_DEFAULT_ALLOCATOR > class GenericValue { public: //! Name-value pair in an object. typedef GenericMember<Encoding, Allocator> Member; typedef Encoding EncodingType; //!< Encoding type from template parameter. typedef Allocator AllocatorType; //!< Allocator type from template parameter. typedef typename Encoding::Ch Ch; //!< Character type derived from Encoding. typedef GenericStringRef<Ch> StringRefType; //!< Reference to a constant string typedef typename GenericMemberIterator<false,Encoding,Allocator>::Iterator MemberIterator; //!< Member iterator for iterating in object. typedef typename GenericMemberIterator<true,Encoding,Allocator>::Iterator ConstMemberIterator; //!< Constant member iterator for iterating in object. typedef GenericValue* ValueIterator; //!< Value iterator for iterating in array. typedef const GenericValue* ConstValueIterator; //!< Constant value iterator for iterating in array. typedef GenericValue<Encoding, Allocator> ValueType; //!< Value type of itself. typedef GenericArray<false, ValueType> Array; typedef GenericArray<true, ValueType> ConstArray; typedef GenericObject<false, ValueType> Object; typedef GenericObject<true, ValueType> ConstObject; }
解决方案
问题根源
编译错误明确指出:传给ReadMyData的obj是GenericMember(键值对)类型,但方法参数要求的是GenericObject类型,类型不匹配导致模板参数推导失败。遍历doc.GetObj()得到的每个元素是键值对,而非对象本身,需要访问该成员的value部分。
修正步骤
- 修正调用代码:传递
obj.value而非整个obj:
if ("My_data" == obj.name) { ReadMyData(obj.value, output); continue; }
- 调整方法参数类型:根据需求选择以下两种方式之一:
- 方式一:接收GenericValue,内部转为对象
适合需要先验证类型的场景:// 头文件声明 template<typename T> void ReadMyData(const rapidjson::GenericValue<T>& val, std::string& output); // 实现部分 template<typename T> void CMyClass::ReadMyData(const rapidjson::GenericValue<T>& val, std::string& output) { RAPIDJSON_ASSERT(val.IsObject()); // 确保是对象类型 const auto& obj = val.GetObject(); // 在这里处理obj的业务逻辑 } - 方式二:直接接收ConstObject
适合确定传入值一定是对象的场景:// 头文件声明 void ReadMyData(const rapidjson::ConstObject& obj, std::string& output); // 实现部分 void CMyClass::ReadMyData(const rapidjson::ConstObject& obj, std::string& output) { // 直接处理obj的业务逻辑 } // 调用时需要转换类型 ReadMyData(obj.value.GetObject(), output);
- 方式一:接收GenericValue,内部转为对象
另外注意:你实现部分的参数写错了,声明里是std::string& output,但实现里写成了SWeather& output,这也会导致编译问题,需要保持参数类型一致。
内容的提问来源于stack exchange,提问作者Flaviu_
相关产品推荐
相关产品推荐

