'Template issue with nlohmann::json
Here's my code and the error, and below I'll show some code that works.
#include <iostream>
#include <string>
#include <nlohmann/json.hpp>
using JSON = nlohmann::json;
using std::cout;
using std::endl;
using std::string;
template <class ObjectType>
void dump(const JSON &json) {
for (auto &[key, value]: json.items()) {
string foo = value.get<std::string>();
cout << "Key: " << key;
cout << " Value: " << foo << endl;
}
}
int main(int, char **) {
JSON json;
json["alpha"] = "beta";
dump<string>(json);
}
-$ g++ -std=c++17 Foo.cpp -o Foo && Foo
Foo.cpp: In function ‘void dump(const JSON&)’:
Foo.cpp:14:37: error: expected primary-expression before ‘>’ token
14 | string foo = value.get<std::string>();
| ^
Foo.cpp:14:39: error: expected primary-expression before ‘)’ token
14 | string foo = value.get<std::string>();
| ^
If I comment out the template
line and change the call in main to dump(json)
, everything works.
My real problem is actually inside a template class, not a template function, but this is the most simplified version I could create. What I really want is this line:
ObjectType obj = value.get<ObjectType>();
But that would be the next step.
Does anyone know what I'm doing wrong and how to fix it?
Solution 1:[1]
While it works as-is with MSVC and Clang, in order to get it to compile on GCC without changing the structure or assignment of variables, GCC requires the template disambiguator for dependent types specified in order for it to be correctly parsed.
Snippet:
using JSON = nlohmann::json;
template <class ObjectType>
void dump(const JSON &json) {
for (auto &[key, value]: json.items()) {
std::string foo = value.template get<std::string>(); // Here
std::cout << "Key: " << key;
std::cout << " Value: " << foo << endl;
}
}
This is due to value.get<std::string>()
being parsed as value.get < ...
i.e. value.get
followed by the less than operator.
I am wondering whether the reason that this occurs when the function is templated is due to template deduction rules and the existing templating provided for the nlohmann::JSON
type which ultimately means the compiler already believes that it has deduced the template type for value.get
before parsing the subsequent template specialisation value.get<std::string>
.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | C2P1 |