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.2k stars 516 forks source link

Variant in container is accessed by value instead of reference #1380

Open MJCollett opened 2 years ago

MJCollett commented 2 years ago

The value of a C++ variant exposed in Lua can be modified. Elements of a C++ vector exposed in Lua can usually be modified. But elements of a vector of variants seem to be returned by value instead of reference, so cannot be modified in place.

The following code passes three copies of a vector into Lua, and attempts to modify them by each of the above routes (in a variant, in a vector, in a vector of variants).

#include <sol/sol.hpp>

#include <variant>
#include <vector>

using Vector = std::vector<int>;
using Variant = std::variant<bool, double, std::string, Vector>;

int main () {
    sol::state lua;
    lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::math, sol::lib::table);

    Vector vec = std::vector<int>{10, 20};
    std::vector<Vector> vectorVec;
    vectorVec.push_back(vec);
    lua["vectorVec"] = vectorVec;

    Variant var = vec;
    std::vector<Variant> variantVec;
    variantVec.push_back(var);
    lua["variant"] = var;
    lua["variantVec"] = variantVec;

    lua.script(R"lua(
        table.insert(variant, 30)
        print(#variant)
        table.insert(vectorVec[1], 40)
        print(#vectorVec[1])
        table.insert(variantVec[1], 50)
        print(#variantVec[1])
    )lua");

}

The expected results are 3, 3, 3: the actual results are 3, 3, 2, indicating that the table insertion is modifying a copy of variantVec[1] rather than the value held in the vector.

Is there any way I can persuade Sol to give Lua access by reference in the third case?

(This is using Sol 3.3.0 with Lua 5.3.3 in C++17 compiled by XCode 10.3 on MacOS 10.14.6.)