Skip to content

2.1.1+ breaks compilation of shared_ptr<json> == 0 #610

Description

@vslavik

v2.1.1 introduced regression that breaks compilation of existing code that compiled with up to v2.1.0. The breakage was introduced in #415 (fixing #414) and relates to over-reaching template operator==.

Code that uses std::shared_ptr<json> and compares it with zero (both == 0 and != 0) no longer compiles due to operator ambiguity that is not immediately (or even no so immediately...) apparent to a mere human like me, but nevertheless I confirmed was caused by #415.

This is enough to reproduce:

#include <json.hpp>

int main()
{
    std::shared_ptr<nlohmann::json> p;
    if (p==0) {
    }
    return 0;
}

This doesn't make the compiler happy:

$ clang++ —std=c++14 test.cpp
test.cpp:16:10: error: use of overloaded operator '==' is ambiguous (with operand types
      'std::shared_ptr<nlohmann::json>' (aka 'shared_ptr<basic_json<> >') and 'int')
    if (p==0) {
        ~^ ~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:4922:1: note: 
      candidate function [with _Tp = nlohmann::basic_json<std::map, std::vector, std::__1::basic_string<char>, bool,
      long long, unsigned long long, double, std::allocator, adl_serializer>]
operator==(const shared_ptr<_Tp>& __x, nullptr_t) _NOEXCEPT
^
json.hpp:6334:17: note: candidate function
      [with ScalarType = int, $1 = 0]
    friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
                ^
json.hpp:6253:17: note: candidate function
    friend bool operator==(const_reference lhs, const_reference rhs) noexcept
                ^
1 error generated.
$

Yes, it would be better to compare with nullptr or use implicit conversion to bool, and it would be trivial to fix the above example, but you don't always have a choice… such as when using another library where this happens internally to it. To name a prominent example, Boost.Thread is affected:

#define BOOST_THREAD_VERSION 4
#include <boost/thread/future.hpp>
#include <json.hpp>

int main()
{
    boost::future<nlohmann::json> f;
    f.get();
    return 0;
}

results in

boost/thread/future.hpp:1683:31: error: use of overloaded operator '==' is
      ambiguous (with operand types 'future_ptr' (aka 'shared_ptr<detail::shared_state<basic_json<std::map, std::vector,
      basic_string<char>, bool, long long, unsigned long long, double, std::allocator, adl_serializer> > >') and 'int')
            if (this->future_ == 0)
                ~~~~~~~~~~~~~ ^  ~
test.cpp:11:7: note: in instantiation of member function 'boost::future<nlohmann::basic_json<std::map, std::vector,
      std::__1::basic_string<char>, bool, long long, unsigned long long, double, std::allocator, adl_serializer> >::get'
      requested here
    f.get();
      ^
boost/smart_ptr/shared_ptr.hpp:814:31: note: candidate function [with T =
      boost::detail::shared_state<nlohmann::basic_json<std::map, std::vector, std::__1::basic_string<char>, bool, long
      long, unsigned long long, double, std::allocator, adl_serializer> >]
template<class T> inline bool operator==( shared_ptr<T> const & p, boost::detail::sp_nullptr_t ) BOOST_NOEXCEPT
                              ^
json.hpp:6334:17: note: candidate function
      [with ScalarType = int, $1 = 0]
    friend bool operator==(const_reference lhs, const ScalarType rhs) noexcept
                ^
json.hpp:6253:17: note: candidate function
    friend bool operator==(const_reference lhs, const_reference rhs) noexcept
                ^
1 error generated.

Observed with both clang-802.0.42 and Visual Studio 2015, so this isn't compiler-specific.

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmedsolution: wontfixthe issue will not be fixed (either it is impossible or deemed out of scope)

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions