有没有办法有效地将 rapidjson 与 std::string 一起使用?
Is there way to use rapidjson with std::string efficiently?
我正在尝试使用rapidjson。
我想生成字符串并将其添加到对象的某些rapidjson::Value
。
我在使用 qjson 时使用 std::string,但在 rapidjson 的情况下,这似乎不合适。我不想生成字符串然后复制它,字符串对象生命周期在对象(rapidjson::Value
)生命周期之前结束(因此generated_string.c_str()
不是这种情况)。 json 中可能有 \0,因此,char*
以 null 结尾的字符串也不是解决方案。
那么,我必须编写自己的字符串类型吗?或者使用类似的东西
auto create_string_object() -> rapidjson::GenericStringRef<char>
{
size_t len;
char* result;
// generate char* result with length len
const char* return_value = result;
return rapidjson::StringRef(return_value,len);
}
auto create_object_object(rapidjson::Document::AllocatorType &allocator) -> rapidjson::Value
{
// ...
rapidjson::Value result(rapidjson::kObjectType);
rapidjson::Value tmp; // tmp = create_string_object() will not compile
tmp = create_string_object();
result.AddMember("key", tmp, allocator);
// ...
}
或者还有其他一些方法可以使用字符串?这对我来说似乎很难。我们不能将字符串移动到rapidjson::Value
,因为该Value
内部的结构不同,我们不能将Value
内的指针设置为c_str()
,因为字符串会在Value
之前被销毁。 即使有GenericStringRef<char>
我也必须重写几乎所有使用字符串的工作。
顺便问一下,为什么RAPIDJSON_HAS_STDSTRING
默认为 0?工作有些问题?我看到如果我知道字符串生存期将在值生存期之前结束,我可以将字符串复制到rapidjson::Value
并复制指针。
UPD:现在我看到 rapidjson 只释放复制的字符串:
//! Destructor.
/*! Need to destruct elements of array, members of object, or copy-string.
*/
~GenericValue() {
if (Allocator::kNeedFree) { // Shortcut by Allocator's trait
switch(flags_) {
case kArrayFlag:
for (GenericValue* v = data_.a.elements; v != data_.a.elements + data_.a.size; ++v)
v->~GenericValue();
Allocator::Free(data_.a.elements);
break;
case kObjectFlag:
for (MemberIterator m = MemberBegin(); m != MemberEnd(); ++m)
m->~Member();
Allocator::Free(data_.o.members);
break;
case kCopyStringFlag:
Allocator::Free(const_cast<Ch*>(data_.s.str));
break;
default:
break; // Do nothing for other types.
}
}
}
因此,正如在回答中所说,以诸如我的代码中的方式使用GenericStringRef
是一个坏主意,因为在这种情况下,我必须自己管理内存。
我不完全理解这个问题。但我试图在这里澄清一些事情。
GenericStringRef
用于防止字符串复制。仅当已知字符串的生存期足够时,才应使用它。对于动态创建的字符串,通常不应使用GenericStringRef
。- 设置
RAPIDJSON_HAS_STDSTRING=1
就可以了。默认情况下,它未打开,因为它的支持是在早期发布后添加的。而且,如果用户不需要,我不希望RapidJSON标头包含<string>
。由于您使用std::string
,您可以将其打开。它应该使您更容易处理std::string
。
相关文章:
- 如何将 string.erase() 与指针一起使用?
- 如何将 OutputDebugString 与 std::string 一起使用?
- 为什么重载运算符不与 std::string 一起使用 msvc /MD 标志
- 为什么 std::unordered_map 不能与 const std::string 键一起使用?
- 反转 C++ 中的 std::string 如何与此构造函数一起使用?
- 对象的序列化向量为STD :: String,以与MPI一起使用
- 将 std::string 传递给 C++ DLL 以便与 C# dll 一起使用
- 可以将std::getline()与从std::string中移出的字符串一起使用吗
- 将自己的迭代器与 std::string 一起使用
- 有没有办法有效地将 rapidjson 与 std::string 一起使用?
- 将TaskDialogConfig与STD :: String一起使用
- 为什么VS UnitTest框架中的Assert::AreEqual不能与std::string一起使用?
- std::replace_copy 与 std::string 一起使用的奇怪行为
- 获取指向成员std::string::size的指针无法与libc++链接,但可以与libstdc++一起使用
- 不能将 boost::stream 与 std::string<unsigned char> 一起使用来实例化 boost::binary_oarchive 或 boost::binary
- 将 %s 格式说明符与 boost::format 和 std::string 一起使用
- 为什么我不能将 std::string 与 libcurl 一起使用?
- std::string在与unordered_sets一起使用时是否需要哈希函数
- 将regex_search与std::string一起使用时的无限循环
- 将make_iterator_range与std::string一起使用