Search code examples
c++jsonrapidjson

C++ std::vector to JSON Array with rapidjson


I am trying to parse a basic std::vector of strings to json using the rapidjson library.

Even though there are multiple answers to this question online, none of it worked for me. The best I could find was this, but I do get an error (cleaned up a bit):

Error C2664 'noexcept': cannot convert argument 1 from 'std::basic_string,std::allocator>' to 'rapidjson::GenericObject,rapidjson::MemoryPoolAllocator>>'

My code is mostly based on the link above:

rapidjson::Document d;
std::vector<std::string> files;

// The Vector gets filled with filenames,
// I debugged this and it works without errors.
for (const auto & entry : fs::directory_iterator(UPLOAD_DIR))
    files.push_back(entry.path().string());

// This part is based on the link provided
d.SetArray();

rapidjson::Document::AllocatorType& allocator = d.GetAllocator();
for (int i = 0; i < files.size(); i++) {
    d.PushBack(files.at(i), allocator);
}
rapidjson::StringBuffer strbuf;
rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
d.Accept(writer);

jsonString = strbuf.GetString();

It would be nice if someone could explain what I am missing here, as I do not fully understand the error showing up. I guess it has to do something with the provided string types, but the error is generated in a Rapidjson file..

I also would appreciate if there were other working examples you could provide.

Thanks in advance!

EDIT With JSON Array I mean just a basic json string containing the values of the vector.


Solution

  • Seems that the string type std::string and rapidjson::UTF8 are not compatible. I set up a small test program, and it seems to work if you create a rapidjson::Value object and call it SetString method first.

    #include <iostream>
    #include <vector>
    #include "rapidjson/document.h"
    #include "rapidjson/writer.h"
    #include "rapidjson/stringbuffer.h"
    
    int main() {
        rapidjson::Document document;
        document.SetArray();
    
        std::vector<std::string> files = {"abc", "def"};
        rapidjson::Document::AllocatorType& allocator = document.GetAllocator();
        for (const auto file : files) {
            rapidjson::Value value;
            value.SetString(file.c_str(), file.length(), allocator);
            document.PushBack(value, allocator);
            // Or as one liner:
            // document.PushBack(rapidjson::Value().SetString(file.c_str(), file.length(), allocator), allocator);
        }
    
        rapidjson::StringBuffer strbuf;
        rapidjson::Writer<rapidjson::StringBuffer> writer(strbuf);
        document.Accept(writer);
    
        std::cout << strbuf.GetString();
    
        return 0;
    }