Skip to content

Deserialization: if class is_constructible from std::string wrong from_json overload is being selected, compilation failed #3171

Closed
@BakhmutR

Description

@BakhmutR

When some hierarchy exists and base class has overload for from_json function, but if child is constructible from string compilation failing because compiler selecting overload void from_json(const BasicJsonType& j, ConstructibleStringType& s) over function that was prepared for base class void from_json(const json& j, Base& b)

What is the issue you have?

As described above, and looks like that on previous release versions it was working as expected. (Code compiles and deserialization was correct).
If add specific from_json overload for derived class, everything is working as expected.

Bug can be reproduced on latest develop branch, checked from 3.9.1 to 3.10.3 code compiles as expected.

Looks like this is regression commit.

Please describe the steps to reproduce the issue.

Can you provide a small but working code example?

https://godbolt.org/z/e75a67oTj

What is the expected behavior?

Compilation should be successful, base class overload should be selected over overload for classes that can be constructed from string.

And what is the actual behavior instead?

Compilation failed.
But if specific from_json overload for derived class was added, everything is working as expected.

Which compiler and operating system are you using?

  • Compiler: clang version 11.0.0, clang version 9.0.0, g++ 11.2.0
  • Operating system: Ubuntu 18.04

Which version of the library did you use?

  • latest release version 3.10.4
  • other release - please state the version: 3.9.1 - 3.10.3
  • the develop branch

If you experience a compilation error: can you compile and run the unit tests?

  • yes
  • no - please copy/paste the error message below
opt/compiler-explorer/libs/nlohmann_json/trunk/single_include/nlohmann/json.hpp:4042:7: error: no viable overloaded '='
    s = *j.template get_ptr<const typename BasicJsonType::string_t*>();
    ~ ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/nlohmann_json/trunk/single_include/nlohmann/json.hpp:4401:16: note: in instantiation of function template specialization 'nlohmann::detail::from_json<nlohmann::basic_json<>, B, 0>' requested here
        return from_json(j, std::forward<T>(val));
               ^
/opt/compiler-explorer/libs/nlohmann_json/trunk/single_include/nlohmann/json.hpp:5060:9: note: in instantiation of function template specialization 'nlohmann::detail::from_json_fn::operator()<nlohmann::basic_json<>, B &>' requested here
        ::nlohmann::from_json(std::forward<BasicJsonType>(j), val);
        ^
/opt/compiler-explorer/libs/nlohmann_json/trunk/single_include/nlohmann/json.hpp:20583:36: note: in instantiation of function template specialization 'nlohmann::adl_serializer<B>::from_json<const nlohmann::basic_json<> &, B>' requested here
        JSONSerializer<ValueType>::from_json(*this, ret);
                                   ^
/opt/compiler-explorer/libs/nlohmann_json/trunk/single_include/nlohmann/json.hpp:20726:16: note: in instantiation of function template specialization 'nlohmann::basic_json<>::get_impl<B, 0>' requested here
        return get_impl<ValueType>(detail::priority_tag<4> {});
               ^
<source>:17:8: note: candidate function (the implicit copy assignment operator) not viable: no known conversion from 'const nlohmann::basic_json<>::string_t' (aka 'const std::basic_string<char>') to 'const B' for 1st argument
struct B : public A

Metadata

Metadata

Assignees

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions