g++ 4.8.5 and nlohmann/3.7.3, error: value-initialization of reference type 'const nlohmann::basic_json<>&' when compiler example
#include <iostream>
#include <functional>
#include <map>
#include "nlohmann/json.hpp"
void Foo(const nlohmann::json &j) {
std::cout<<j.dump()<<std::endl;
}
using Handler = std::function<void(const nlohmann::json&)>;
int main() {
std::map<int, Handler> handlers;
handlers.emplace(1, std::bind(Foo, std::placeholders::_1));
for(auto &i : handlers) {
i.second(nlohmann::json{{"data", "123"}});
}
}
g++ test.cpp -o main
here is the simplest example online:
compile pass
compiler error
develop branchCan you please try to compile the test suite? As the used compiler (GCC 4.8.5) is quite old, this may be a bug in its C++11 implementation.
I tried to cross build unit test and it is ok. @nlohmann
I used jsonformoderncpp/3.4.0@vthiery/stable before. This version is ok for gcc 4.8.5. However, this vesion is not maintained by conan official. nlohmann_json jsonformoderncpp
This is caused by json's template<typename ValueType> operator ValueType() const;, which ends up getting invoked as part of the process of trying to match a json object to the const json& parameter of the bound function.
see #958 for discussion on the topic.
edit I managed to isolate the specific part of the bind process that's failing:
This produces the same error:
void foo() {
nlohmann::json v;
std::tuple<nlohmann::json&> x{v};
}
In the end, this boils down to the following question:
Should the following be able to compile?
bool test = std::is_default_constructible<std::tuple<int&>>::value;
https://gcc.godbolt.org/z/6vwHuM
I'd say that the answer is evidently yes. And it's pretty obvious to me that it's GCC 4.8.5 that's broken here.
Now the only remaining question is: Is it worthwhile to work around this compiler bug or not? I tried sprinkling a few remove_reference in the code path to no avail. So the answer will most likely be of non-trivial complexity.
My take would be: if we get rid of the allegedly evil operator T(), then this goes away, otherwise, I don't think fixing this is worth the trouble.
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.
Maybe related: #2226
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.
Most helpful comment
In the end, this boils down to the following question:
Should the following be able to compile?
https://gcc.godbolt.org/z/6vwHuM
I'd say that the answer is evidently yes. And it's pretty obvious to me that it's GCC 4.8.5 that's broken here.
Now the only remaining question is: Is it worthwhile to work around this compiler bug or not? I tried sprinkling a few
remove_referencein the code path to no avail. So the answer will most likely be of non-trivial complexity.My take would be: if we get rid of the allegedly evil
operator T(), then this goes away, otherwise, I don't think fixing this is worth the trouble.