Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

call of overloaded for push_back and operator+= is ambiguous #1352

Closed
JunYoung-Jo opened this issue Nov 13, 2018 · 9 comments
Closed

call of overloaded for push_back and operator+= is ambiguous #1352

JunYoung-Jo opened this issue Nov 13, 2018 · 9 comments
Labels
state: help needed the issue needs help to proceed state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated

Comments

@JunYoung-Jo
Copy link

First, I'm sorry I can not speak English well.
English isn't my first language, so please excuse any mistakes.

  • What is the issue you have?

When I try to insert a std :: pair using push_back() or operator+=(), a call ambiguous error occurs.

  • Please describe the steps to reproduce the issue. Can you provide a small but working code example?
pair<string,bool> value = {"key1",true};
json j = json::array();
j.push_back(value);
j+=value;

or

pair<string,bool> value = {"key1",true};
json j = json::object();
j.push_back(value);
j+=value;
  • What is the expected behavior?
pair<string,bool> value = {"key1",true};

json arr = json::array();
arr.push_back(value);
//[["key1",true]]

json obj = json::object();
obj.push_back(value);
//{"key1",true}
  • And what is the actual behavior instead?

Compile error

error: call of overloaded ‘push_back(std::pair<std::__cxx11::basic_string<char>, bool>&)’ is ambiguous j.push_back(value);

GCC 7.3.0

Did i miss anything?

@JunYoung-Jo
Copy link
Author

JunYoung-Jo commented Nov 13, 2018

I think the reason for the error is that the std :: pair type can be implicitly converted into two types: basic_json and object_t :: value_type.

To solve this error, I suggest changing the name of the function

void push_back(const typename object_t::value_type& val)

to

void insert (const typename object_t :: value_type & val)

In fact, the json :: object is not inserted at the end when inserting a new element.

So the name of the function to insert the new element does not have to be push_back.

I also think that the function name "insert ()" is better suited to the STL style because the json :: object type uses the std :: map type or the std :: unordered_map type as the container.

But I can not think of a way to solve the ambiguity problem of operator + =.
Is there a way to resolve all errors in both functions?

@JunYoung-Jo
Copy link
Author

I've been waiting for an answer.
but no one answered.
is this a bad or wrong question?
or did I do something wrong?
so should I close this issue?

@nlohmann
Copy link
Owner

Everything is fine - I just did not find the time to work on this.

@JunYoung-Jo
Copy link
Author

Okay. I will wait for an answer. Thanks for the reply.

@JunYoung-Jo
Copy link
Author

If you do not like the above solution, I suggest removing the to_json function for the std :: pair.

I have confirmed that std :: pair is created as a json :: array.
However, you do not need to create an array of size 2 using a pair, and you can use tuples.

I also checked every test case.
The only problem when removing the to_json function for std :: pair is the 'array of pair' case in the conversions.cpp file.

If you do not really need to convert 'std :: map' to 'json :: array', I think it is a good solution to remove the to_json function for std :: pair.

You can use this feture by removing the to_json function for std :: pair:

    std::map<std::string,int> map{{"json1",2},{"neednot",4}, {"json2",3}};

    json obj;

    for (const auto &it : map){
        if(it.first.find("json") != std::string::npos){
            obj.push_back(it);
        }
    }

    std::cout << obj << std::endl;              //{"json1":2,"json2":3}

also this :

    std::map<std::string,int> map{{"json1",2},{"neednot",4}, {"json2",3}};

    json obj;

    for (const auto &it : map){
        if(it.first.find("json") != std::string::npos){
            obj += it;
        }
    }

    std::cout << obj << std::endl;              //{"json1":2,"json2":3}

I think this feature is much more useful than converting 'std :: map' to 'json :: array'.
I know you have no time to review this issue.
However, I hope to review this issue someday.

@theodelrieu
Copy link
Contributor

I do not think removing the std::pair support is a good idea. Not to mention it will break a lot of code.

Currently, std::pair<basic_json::string_t, CONVERTIBLE_TO_JSON> will be converted as a JSON object.

If the key is not basic_json::string_t, it will be converted as an array.

I believe the best thing to do is to fix push_back itself. Maybe keeping the void push_back(basic_json) overloads is enough. We need to handle arrays and object in the single push_back overload then.

@nlohmann
Copy link
Owner

I agree with @theodelrieu - removing support for std::pair is a breaking change that I am not willing to make for this issue. It would be great if the idea to fix push_back would be followed instead.

@nlohmann nlohmann added the state: help needed the issue needs help to proceed label Dec 22, 2018
@stale
Copy link

stale bot commented Jan 26, 2019

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated label Jan 26, 2019
@stale stale bot closed this as completed Feb 6, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
state: help needed the issue needs help to proceed state: stale the issue has not been updated in a while and will be closed automatically soon unless it is updated
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants
@nlohmann @theodelrieu @JunYoung-Jo and others