ThePhD / sol2

Sol3 (sol2 v3.0) - a C++ <-> Lua API wrapper with advanced features and top notch performance - is here, and it's great! Documentation:
http://sol2.rtfd.io/
MIT License
4.06k stars 493 forks source link

How to do table iteration recursion? #1465

Closed MeowZanetti closed 1 year ago

MeowZanetti commented 1 year ago

Hello. I am writing a table-to-json converter, everything works well, but if I put a table into a table, and this table into another table, the compiler gives an error: cannot use operator[] with a string argument with array.

Perhaps recursion is needed here, I don’t understand how to do it very well, I need help.

I'm trying to use a lua table like this:

local arr = {
param = {'text1', param_in = {'test2'}}
}
Rochet2 commented 1 year ago

Does not look like the error comes from sol. The error comes from the json library as your code tries to first use j like an array and then like an object. You sure it is the compiler throwing the error? Or did the error actually occur during runtime.

The for loop for the values in param starts. I assume 'text1' value has a number as key implicitly, for example 0. This causes the following code to run.

// The key is a number
        else if (pair.first.get_type()==sol::type::number) {
            if (type==sol::type::nil || type==sol::type::none)
                j.push_back(nullptr);
// The value is a string
            else if (type==sol::type::string) {
// We treat j as an array so it is implicitly converted into one according to the library's docs (nlohmann/json)
                j.push_back(pair.second.as<std::string>());
            }

Then the for loop goes to the next key-value pair, so param_in is being processed and it runs the following code

// The key is clearly a string
        if (pair.first.get_type()==sol::type::string) {
            if (type==sol::type::nil || type==sol::type::none)
                j[pair.first.as<std::string>()] = nullptr;
            else if (type==sol::type::string) {
                j[pair.first.as<std::string>()] = pair.second.as<std::string>();
            }
// The value is a table
            else if (type==sol::type::table) {
                sol::table a = pair.second.as<sol::table>();
// We treat j as an object. But it is already treated as an array! So library probably throws.
                j[pair.first.as<std::string>()] = lua2json(a); // During iteration of the third table, no value is assigned to this row
            }
        }