有没有办法有效地使用rapidjson和std :: string?

时间:2015-05-10 22:44:33

标签: c++ string rapidjson

我正在尝试使用rapidjson。

我想生成字符串并将其添加到对象的rapidjson::Value

我在使用qjson时使用std :: string,但是在rapidjson的情况下,它似乎不合适。我不想生成字符串然后复制它,字符串对象生存期在对象(rapidjson::Value)生存期之前结束(因此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之前被销毁1}}。 即使使用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是一个坏主意,因为在这种情况下我必须自己管理内存。

1 个答案:

答案 0 :(得分:8)

我不完全理解这个问题。但我试着在这里澄清一些事情。

  1. GenericStringRef用于防止字符串复制。只有在知道字符串的生命周期足够时才应该使用它。对于动态创建的字符串,通常不应使用GenericStringRef
  2. 设置RAPIDJSON_HAS_STDSTRING=1很好。它默认情况下不会打开,因为它的支持是在早期发布后添加的。如果用户不需要,我不希望RapidJSON标头包含<string>。由于您使用std::string,因此可以将其启用。它应该可以让您更轻松地处理std::string