I'd like to expose a const container (here it happens to be a std::vector) to Lua via Sol, so it can be iterated/accessed there but not modified. I thought that exposing a const ref to the thing (rather than a ref) would prevent modifications to it via Lua, but there is no error when I try to add elements in various ways; I actually manage to modify the "const" declared C++ vector!
Compiler: Visual Studio 2022, C++17 or C++20
OS: Windows 11 Pro
Here is an example that shows the problem, and what I'm trying to do. It's basically a slightly modified version of your example from the documentation, but where I tried to make the vector constant:
#include "sol/sol.hpp"
int main() {
sol::state lua;
lua.open_libraries(sol::lib::base, sol::lib::package, sol::lib::os, sol::lib::string);
lua.script(R"lua(
function printContainer(x)
print("\ncontainer has:")
for k = 1, #x do
v = tostring(x[k])
print("\t", k, v)
end
end
)lua");
sol::function printContainer = lua["printContainer"];
// Expose a constant vector to Lua
// (first tried exposing as a cref, and then I even tried setting the underlying variable as const!)
auto const arr = std::vector<int>{ 2, 4, 6, 8, 10 };
lua["arr"] = std::cref(arr);
printContainer(lua["arr"]);
std::cout << "Size of C++ arr: " << arr.size() << '\n';
// Presumably we shouldn't be able to get a non-const reference to it...?
std::vector<int>& reference_to_arr = lua["arr"];
reference_to_arr.push_back(12);
// See *6* elements printed out (but it's supposed to be const)
printContainer(lua["arr"]);
std::cout << "Size of C++ arr: " << arr.size() << '\n';
// Modify it from Lua
lua.script(R"(
arr:add(28)
)");
// See *7* elements printed out (again, it's intended to be const)
printContainer(lua["arr"]);
std::cout << "Size of C++ arr: " << arr.size() << '\n';
return 0;
}
The program outputs:
container has:
1 2
2 4
3 6
4 8
5 10
Size of C++ arr: 5
container has:
1 2
2 4
3 6
4 8
5 10
6 12
Size of C++ arr: 6
container has:
1 2
2 4
3 6
4 8
5 10
6 12
7 28
Size of C++ arr: 7
Ideally, I'd like to have the exposing as const "just work", but I guess it may be necessary to create my own container type...? I would expect it to give an error if I try to modify it. Maybe something like what happens if I use a const variable in Lua and then try to change it:
local x <const> = 3
x = 7
Which produces:
[sol2] An error occurred and has been passed to an error handler: sol: syntax error: [string "..."]:3: attempt to assign to const variable 'x'
I'd like to expose a const container (here it happens to be a
std::vector
) to Lua via Sol, so it can be iterated/accessed there but not modified. I thought that exposing a const ref to the thing (rather than a ref) would prevent modifications to it via Lua, but there is no error when I try to add elements in various ways; I actually manage to modify the "const" declared C++ vector!Compiler: Visual Studio 2022, C++17 or C++20 OS: Windows 11 Pro
Here is an example that shows the problem, and what I'm trying to do. It's basically a slightly modified version of your example from the documentation, but where I tried to make the vector constant:
The program outputs:
Ideally, I'd like to have the exposing as const "just work", but I guess it may be necessary to create my own container type...? I would expect it to give an error if I try to modify it. Maybe something like what happens if I use a const variable in Lua and then try to change it:
Which produces: