Open percyteng opened 6 years ago
Did you take a look at the crow::json::wvalue class?
You'll see that crow::json::wvalue
has a move-assignment operator:
wvalue& operator=(std::vector<wvalue>&& v)
And crow::response has constructors that accept a reference and rvalue of crow::json::wvalue
.
So this should work
CROW_ROUTE(...
{
std::vector<crow::json::wvalue> vector_of_wvalue;
// fill vector
// ...
crow::json::wvalue final = std::move(vector_of_wvalue);
return crow::response(std::move(final));
});
Moving the contents of the std::vector into crow::json::wvalue doesn't seem to work; the line crow::json::wvalue result = std::move(crew_members);
below is problematic?
CROW_ROUTE(app, "/crew")
([]{
crow::json::wvalue troi;
troi["name"] = "Deanna Troi";
troi["ship"] = "Enterprise";
troi["captain"] = "Jean-Luc Picard";
crow::json::wvalue riker;
riker["name"] = "William Riker";
riker["ship"] = "Enterprise";
riker["captain"] = "Jean-Luc Picard";
std::vector<crow::json::wvalue> crew_members;
crew_members.push_back(troi);
crew_members.push_back(riker);
crow::json::wvalue result = std::move(crew_members);
return crow::response(std::move(result));
});
Produces:
error: no viable conversion from 'typename remove_reference<vector<wvalue, allocator<wvalue> > &>::type' (aka 'std::__1::vector<crow::json::wvalue, std::__1::allocator<crow::json::wvalue> >') to 'crow::json::wvalue'
[build] crow::json::wvalue result = std::move(crew_members);
Is this class supposed to work this way?
Looks like you're right.
You can add the following constructor to crow::json::wvalue
for it to compile.
Up to you to actually test it though.
wvalue(std::vector<wvalue>&& v)
{
l = std::unique_ptr<std::vector<wvalue>>(new std::vector<wvalue>{});
l->resize(v.size());
size_t idx = 0;
for(auto& x:v)
{
(*l)[idx++] = std::move(x);
}
}
Alternatively, you can also just do.
CROW_ROUTE(app, "/crew")([]() {
std::vector<crow::json::wvalue> vec;
crow::json::wvalue wv;
wv = std::move(vec);
return crow::response(std::move(wv));
});
Even with your constructor code and other examples, I still couldn't get this working.
I resorted to using nlohmann-json:
CROW_ROUTE(app, "/crew")
([]{
nlohmann::json troi = {
{ "name", "Deanna Troi" },
{ "ship", "Enterprise" },
{ "captain", "Jean-Luc Picard" }
};
nlohmann::json riker = {
{ "name", "William Riker" },
{ "ship", "Enterprise" },
{ "captain", "Jean-Luc Picard" }
};
nlohmann::json crew = { riker, troi };
return crow::response(crew.dump());
});
I'm not thrilled about adding another library to my project, but this seems to be the only solution, until the Crow JSON library supports std::vector.
I should have tried your code, the problem is that crow::json::wvalue
has the copy constructor implicitly deleted; meaning you cannot call push_back
.
You have to use emplace_back(std::move(troi));
I guess you could also just add a copy constructor :man_shrugging: I can understand using another json library, I eventually did the same.
I also found this solution works:
crow::json::wvalue x;
std::vector<int> ids = {1,2,3};
std::vector<string> names = {"test1", "test2", "test3"};
size_t i;
for (i = 0; i < ids.size(); ++i) {
x[i]["id"] = ids.at(i);
x[i]["name"] = names.at(i);
}
It's possible loaded json file return ?
std::ifstream ifs("example.json");
json jf = json::parse(ifs);
return crow::response(std::move(jf));
Please anyone Help me
Hi @vijaysoul, I hope you found an answer to your question. This worked for me:
ifstream ifs;
ifs.open("example.json");
string str((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
auto jf = crow::json::load(str);
return crow::response(jf);
I didn't see any example. Can someone please help?
My code currently is vector resArr(resMeta->getColumnCount());
int count = 0;
while (result->next()) {
resJson = NULL;
/ Access column data by alias or column name /
for (int i = 1; i <= resMeta->getColumnCount(); i++){
string column = string(resMeta->getColumnName(i));
resJson[column] = result->getString(column);
}
resArr[count] = crow::json::dump(resJson);
count ++;
}
for (int j = 0; j < resMeta->getColumnCount(); j++){
cout << resArr[j] << endl;
}
This way as a kind of work around, I changed json to string and put them in a vector of strings. Any idea how I can send a vector back through response?