Copying Boxed_Values


#1

Suppose I have the following code:

std::vector<chaiscript::Boxed_Value> vals;
chai.add(chaiscript::fun([&vals](chaiscript::Boxed_Value x)
                         { vals.push_back(x); }),
         "add");

chai.eval("for (var i = 0; i < 5; ++i) { add(i) }");

Now if I print out the contents of vals, I’ll get 5 5 5 5 5. I would instead like to see 0 1 2 3 4. I’m guessing the problem is that Boxed_Value really stores a reference to i inside ChaiScript, and so I’m just seeing the last value. How can I make a copy of the value in each call of add()?


#2

You would have to use the ChaiScript ‘clone’ function to not get references to each object.

chai.eval("for (var i = 0; i < 5; ++i) { add(clone(i)) }");

By default the built-in push_back function for std::vector does a clone, so you could also do:

std::vector<chaiscript::Boxed_Value> vals;
chai.add(chaiscript::var(&vals), "vals");

chai.eval("for (var i = 0; i < 5; ++i) { vals.push_back(i) }");

If you were so inclined.

If you really want to do a clone from C++, you would need to do something like:

std::vector<chaiscript::Boxed_Value> vals;
auto clone = chai.eval<std::function<Boxed_Value (const Boxed_Value &)>>("clone");
chai.add(chaiscript::fun([&vals, &clone](chaiscript::Boxed_Value x)
                         { vals.push_back(clone(x)); }),
         "add");

chai.eval("for (var i = 0; i < 5; ++i) { add(i) }");

#3

Ah, perfect. Thanks. It’s the last version that I want (i.e., to really clone from C++). The vector example was just a stylized illustration. In reality, I want these values stored as a member of a struct, stored in some data structure, later serialized and shipped off to a different processor. But the third solution solves this problem exactly how I want. Thanks again.