Rapidjson: GenericValue::AddMember does not accept const std::string references

Created on 26 Aug 2016  路  9Comments  路  Source: Tencent/rapidjson

GenericValue::AddMember overload for std::basic_string takes non-const reference, but the comment says it should be a constant string reference. It calls GenericValue constructor taking a const reference, so I don't see a reason for it being non-const - probably just an omission of const keyword.

Answered Questions

Most helpful comment

RapidJSON is designed to use move semantics before C++11.
http://rapidjson.org/md_doc_tutorial.html#MoveSemantics

All 9 comments

Ah, I see - after adding const, the call AddMember(name, "value", allocator) is ambiguous between StringRefType and std::basic_string overloads.

The code works fine when calling:

Value o(kObjectType);
const std::string& ref = ...
o.AddMember("sth", ref, allocator);

but fails for:

Value o(kObjectType);
Value other = ...
const std::string& ref = ...
o.AddMember(other, ref, allocator);

I don't know if it's a bug or I'm just using it wrong, I've ended wrapping the string in Value myself before calling AddMember.

In general I would say, why AddMember doesn't support const &?
We have this signature:
GenericValue& AddMember(GenericValue& name, GenericValue& value, Allocator& allocator)
but not this one:
GenericValue& AddMember(const GenericValue& name, const GenericValue& value, Allocator& allocator)

This would prevent a call like this:
dict.AddMember("table", rapidjson::Value(rapidjson::kArrayType), allocator);

Because rvalues must be const.

Because of move semantics, the value is moved into the object.

This is true if C++11 is available, not in pre C++11

RapidJSON is designed to use move semantics before C++11.
http://rapidjson.org/md_doc_tutorial.html#MoveSemantics

Thanks @miloyip
Then, should this call be done like this?

rapidjson::Value value_to_add(rapidjson::kArrayType)
dict.AddMember("table", value_to_add, allocator);

instead of
dict.AddMember("table", rapidjson::Value(rapidjson::kArrayType), allocator);

Your example is one option in C++03. The other option is to explicitly Move() the temporary:

dict.AddMember("table", rapidjson::Value(rapidjson::kArrayType).Move(), allocator);

In C++11, an rvalue reference should work out of the box.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ns-osmolsky picture ns-osmolsky  路  4Comments

leeyiw picture leeyiw  路  4Comments

dan-ryan picture dan-ryan  路  6Comments

lasalvavida picture lasalvavida  路  5Comments

lixiaofan0 picture lixiaofan0  路  3Comments