Skip to content

Static method invites inadvertent logic error. #1433

Description

@madmongo1
  • What is the issue you have?

I recenly wrote code like this:

json jbody;
jbody.parse(upstream_response_.body());
auth_object_.set_user_id(jbody.at("user_id").get<std::string>());

It compiled fine, but subsequent tests failed (i.e. the expected result was not realised at runtime).

2 hours later I realised my mistake. json::parse is a static method that returns a json object. But the compiler was not able to help me discover my mistake early.

Suggestions:

nodiscard

add a [[nodiscard]] directive to the function when detected that the compiler supports it.

deprecate confusing interface

possibly deprecate static json json::parse(...)

deduce json type through ADL

possibly provide an ADL free function overload suite such that the user may call:

json target;
json_parse(target, source, ...); // returns error state or possibly throws

If users wish to have a parse that returns a newly constructed json object, this can be self provided, example:

template<class Source>
auto json parse_to_json(Source&& source) -> nlohmann::json
{
    nlohmann::json result;
    json_parse(result, source);    // located through ADL
    return result;
}

More complex user-defined functions may want to deduce the allocator from the source, making it easier to use the library with custom allocators such as arenas, this improving performance.

E.g.

template<class Ch, Class ChT, class Alloc>
auto json parse_to_json(std::basic_string<Ch, ChT, Alloc> const& source)
{
    // note: nlohmann::value_base might be a new type, used to provide a rebind
    // to internal maps, vectors, etc
    using allocator_type = typename std::allocator_traits<Alloc>::template rebind_alloc<nlohmann::value_base>;

    // note: providing custom allocator as an argument.
    nlohmann::basic_json<....., allocator_type> result(source.get_allocator());
    json_parse(result, source);    // located through ADL. Uses internal allocator
    return result;
}
  • Please describe the steps to reproduce the issue. Can you provide a small but working code example?

see above

  • What is the expected behavior?

I intuitively expected parse to be a member function which would mutate jbody.

  • And what is the actual behavior instead?

The return value was silently discarded.

clang, gcc8, fedora29, osx.

  • Did you use a released version of the library or the version from the develop branch?

released

N/A

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions