Skip to content

clang compile error: use of overloaded operator '<=' is ambiguous with (nlohmann::json{{"a", 5}})["a"] <= 10 #512

@ajneu

Description

@ajneu

Hi,

try compile the following code with clang: clang++-3.9 -std=c++14 -o go main.cpp

// clang++-3.9 -std=c++14 -o go main.cpp

#include "json.hpp"

using json = nlohmann::json;

int main()
{
    json j;
    j["a"] = 5;

    if (j["a"] <= 10) {
        std::cout << "yip:  5 <= 10  !!" << std::endl;
    }
    return 0;
}

We get the following compile error:

main2.cpp:10:16: error: use of overloaded operator '<=' is ambiguous (with operand types 'value_type' (aka 'nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char>,
      bool, long, unsigned long, double, std::allocator, adl_serializer>') and 'int')
    if (j["a"] <= 10) {
        ~~~~~~ ^  ~~
./json.hpp:6161:17: note: candidate function
    friend bool operator<=(const_reference lhs, const_reference rhs) noexcept
                ^
main2.cpp:10:16: note: built-in candidate operator<=(long long, int)
    if (j["a"] <= 10) {
               ^
main2.cpp:10:16: note: built-in candidate operator<=(__float128, int)
main2.cpp:10:16: note: built-in candidate operator<=(unsigned long, int)
main2.cpp:10:16: note: built-in candidate operator<=(unsigned int, int)
main2.cpp:10:16: note: built-in candidate operator<=(long double, int)
main2.cpp:10:16: note: built-in candidate operator<=(int, int)
main2.cpp:10:16: note: built-in candidate operator<=(unsigned long long, int)
main2.cpp:10:16: note: built-in candidate operator<=(__int128, int)
main2.cpp:10:16: note: built-in candidate operator<=(double, int)
main2.cpp:10:16: note: built-in candidate operator<=(long, int)
main2.cpp:10:16: note: built-in candidate operator<=(unsigned __int128, int)
... etc.
1 error generated.

.
.
.

But in comparision: operator== compiles fine:

// clang++-3.9 -std=c++14 -o go main.cpp

#include "json.hpp"

using json = nlohmann::json;

int main()
{
    json j;
    j["a"] = 5;

    if (j["a"] == 5) {
        std::cout << "yip:  5 == 5  !!" << std::endl;
    }
    return 0;
}

.
.
.

Checking the code we see, that operator==, has the following bool operator==(const_reference lhs, const ScalarType rhs)

but operator<=, operator<, operator>= and operator> do not have similar functions handling scalar.

Ultimately I would like to see the following compile under clang:

// clang++-3.9 -std=c++14 -o go main.cpp

#include <cassert>
#include <cstdint>
#include "json.hpp"

using json = nlohmann::json;

#define CHECK_SCALAR(LHS, OP, RHS, RES)                 \
    assert((LHS OP static_cast<  int8_t>(RHS)) == RES); \
    assert((LHS OP static_cast< uint8_t>(RHS)) == RES); \
    assert((LHS OP static_cast< int16_t>(RHS)) == RES); \
    assert((LHS OP static_cast<uint16_t>(RHS)) == RES); \
    assert((LHS OP static_cast< int32_t>(RHS)) == RES); \
    assert((LHS OP static_cast<uint32_t>(RHS)) == RES); \
    assert((LHS OP static_cast< int64_t>(RHS)) == RES); \
    assert((LHS OP static_cast<uint64_t>(RHS)) == RES); \
    assert((LHS OP static_cast<float   >(RHS)) == RES); \
    assert((LHS OP static_cast<double  >(RHS)) == RES);
    

int main()
{
    json j;
    j["a"] = 5;

    // json op scalar
    CHECK_SCALAR(j["a"], ==, 5,  true); // all good!
    CHECK_SCALAR(j["a"], !=, 4,  true); // all good!

    CHECK_SCALAR(j["a"], <=, 7,  true); // clang compile error
    CHECK_SCALAR(j["a"], < , 7,  true); // clang compile error
    CHECK_SCALAR(j["a"], >=, 3,  true); // clang compile error
    CHECK_SCALAR(j["a"], > , 3,  true); // clang compile error


    CHECK_SCALAR(j["a"], <=, 4,  false); // clang compile error
    CHECK_SCALAR(j["a"], < , 4,  false); // clang compile error
    CHECK_SCALAR(j["a"], >=, 6,  false); // clang compile error
    CHECK_SCALAR(j["a"], > , 6,  false); // clang compile error


    
    // scalar op json
    CHECK_SCALAR(5, ==, j["a"],  true); // all good!
    CHECK_SCALAR(4, !=, j["a"],  true); // all good!

    CHECK_SCALAR(7, >=, j["a"],  true); // clang compile error
    CHECK_SCALAR(7, > , j["a"],  true); // clang compile error
    CHECK_SCALAR(3, <=, j["a"],  true); // clang compile error
    CHECK_SCALAR(3, < , j["a"],  true); // clang compile error

    CHECK_SCALAR(4, >=, j["a"],  false); // clang compile error
    CHECK_SCALAR(4, > , j["a"],  false); // clang compile error
    CHECK_SCALAR(6, <=, j["a"],  false); // clang compile error
    CHECK_SCALAR(6, < , j["a"],  false); // clang compile error
    
    return 0;
}

Metadata

Metadata

Assignees

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions