Я пытаюсь работать с rapidjson.Есть ли способ использовать quickjson с std :: string эффективно?
Я хочу сгенерировать строку и добавить ее к rapidjson::Value
, который является объектом.
Я использовал std :: string при работе с qjson, но в случае quickjson это кажется неуместным. Я не хочу генерировать строку, а затем копировать ее, срок жизни объекта объекта перед объектом (rapidjson::Value
) lifetime (поэтому generated_string.c_str()
- это не случай). В json может быть \ 0, поэтому char*
с нулевым символом также не является решением.
Итак, я должен написать собственный тип строки? Или используйте что-то вроде
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
таким образом, например, в моем коде здесь плохо идея, потому что в таком случае я должен сам управлять памятью.
Спасибо. Извините, после некоторого времени размышления я понял, что это плохой вопрос: если я хочу всегда работать с '' 'std :: string''' (и' '' quickjson'''), я должен скопировать строки в некоторых случаях, если я хочу избежать копирования, я должен использовать '' 'char *' '' или некоторые типы из '' 'quickjson''', как в вопросе. – ckorzhik