Sol2 unable to iterate over vector - c++

I'm attempting to give a list of integers to a Lua script, and iterate over them.
The error I'm getting is:
test.lua:12: bad argument #1 to 'pairs' (table expected, got userdata)
stack traceback:
[C]: in function 'pairs'
test.lua:12: in main chunk
The C++ code being used:
#include <sol.hpp>
struct Test {
std::vector<int> a;
};
int main(void) {
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<Test>("test",
"a", &Test::a);
lua.script_file("test.lua", [](lua_State* L, sol::protected_function_result pfr) {
sol::error err = pfr;
std::cout << err.what() << std::endl;
return pfr;
});
}
The Lua script:
t = test.new()
for i in pairs(t.a) do
print(i)
end

SO I know this is an old question, but I came across this problem myself when first learning how to do this so I thought I'd add this answer for anyone coming across this now.
The problem isn't with your C++ code, it's with your Lua code. Lua uses colons ( : ) instead of full stops ( . ) for member calls, so it should look like this:
t = test:new()
for k,v in pairs(t.a) do
print(v)
end
Emphasis on member calls, mind you. Properties are still accessed with full stops. If you have a user type CObject with the function ExFnc, you could call it on object ExampleObj either of the two following ways:
ExampleObj:ExFnc()
or
CObject.ExFnc(ExampleObj)
sol (at least the version I used, 3.0.2) provides a whole assortment of container mappings already included that just work right out of the box. You can find details for them here: sol 3.0.2 containers documentation
It lists automatic compatibility with the following types:
std::vector
std::deque
std::list
std::forward_list
std::array
std::set
std::multi_set
std::map
std::multi_map
std::unordered_set
std::unordered_multiset
std::unordered_map
std::unordered_multimap
Keep in mind though that NAMESPACES in sol are tables, you have to use full stops for those.

pairs is a Lua function that only takes a single variable of type table as input. t is of type userdata, hence the error.
https://www.lua.org/manual/5.3/manual.html#pdf-pairs
You have two options here:
implement a version of pairs that can handle your userdata type
copy all elements into a table befor you feed that into pairs
Also ask yourself if it makes any sense to use pairs on a vector. A numeric for loop would feel much more natural. I'd even prefer ipairs over pairs

Related

Sort function from standard library gives an error using an iterator

I am relatively new to C++ language and trying to implement sort function from algorithm library defined in standard namespace and use std::sort directly.
The common structure to sort a vector using sort is given using iterator and comparison function.
Consider vector v as {4,3,5,9} and after sorting it will look like {9,5,4,3}.
For an instance
std::sort(v.begin(),v.end(),a>b)
So, I wanted to use this method to sort an list of nodes based on heuristic value for my A* search algorithm.Heuristic is basically addition of 2 attributes of Node object and I the sorting operation has to be done vector of this nodes and I want to use
open_list.begin() and open_list.end() as my iterators
to use my compare function as a third argument for std::sort() function here is actual implementation:
std::sort(open_list.begin(),open_list.end(),open_list.begin()->g_value + open_list.begin()->h_value > open_list.end()->g_value + open_list.end()->h_value );
Here, I basically am adding h and g values which are attributes of object Node and
open_list is a vector of pointers to the nodes. I felt my implementation was right but it throws me a weird error which looks like this:
/home/piyushkumar/CppND-Route-Planning-Project/src/route_planner.cpp:65:93: error: request for member ‘h_value’ in ‘((RoutePlanner)this)->RoutePlanner::open_list.std::vector::begin().__gnu_cxx::__normal_iterator >::operator->()’, which is of pointer type ‘RouteModel::Node*’ (maybe you meant to use ‘->’ ?)
std::sort(open_list.begin(),open_list.end(),open_list.begin()->g_value + open_list.begin()->h_value > open_list.end()->g_value + open_list.end()->h_value );
Some clarification regarding the error:
RouteModel is an class and Node inherits from that class. Why this simple comparison function as a 3rd argument fails and says that you should use -> which I have already used to retrieve values of g_value and h_value from Node object.
Any help and leads will be appreciated.
Ok let's sort things out one by one.
First about your error message. Your vector stores pointers and keep in mind that a->b is equivalent to (*a).b, so open_list.begin()->h_value equals to open_list.front().h_value, and a pointer clearly doesn't have member variable. To refer to the member variable, you need to write (*open_list.begin())->h_value. Furthermore, dereferencing .end() gives you undefined behaviour immediately. To access the last element of std::vector, use .back() instead of *(you_vector.end()). (Remember to check the vector is not empty beforehand! Otherwise you will step into undefined behaviour again :) )
Secondly your idea about how to use std::sort is wrong. To sort a range of elements by a "standard" you chose, the first two parameters of sort provide the information about the range, and the third parameter is your "standard", so it must be a "callable", and it takes two parameters and tell std::sort whether the first parameter should be sorted before the second. As a result, to sort v in descending order, you need to call std::sort in the following way:
std::sort(v.begin(), v.end(), [](int a,int b)->bool{ return a > b;});
Here, the third parameter is a lambda expression, if you don't know what the hell it is, google helps you. (FYI callable may not necessarily be a lambda expression, it may also be a function or a functor (a.k.a. function object) but I personally think lambda is the clearest one here.)
I will not give you the statement needed for sorting your open_list, you can use it to check whether you have figured out how the things work or not. Enjoy learning.
Ok, so much not right here.
The third parameter to std::sort is a "callable" (think like a function pointer), which std::sort calls to compare two elements in the sequence. It needs to take two elements of the sequence (usually by const & and return a bool.
Your example std::sort(v.begin(),v.end(),a>b) will not work, because a>b is not callable.
Your "real" code suffers from the same problem.
std::sort(open_list.begin(),
open_list.end(),
open_list.begin()->g_value + open_list.begin()->h_value >
open_list.end()->g_value + open_list.end()->h_value );
That big expression is not callable, and that's why the compiler is complaining.
Also, FWIW, open_list.end() is an iterator to the "one past the end" position in the sequence, and dereferencing it (as you do in open_list.end()->g_value) is undefined behavior, since there's no element there.
See cppreference for more info.

Creating Duplicate Elements in an Array using Higher-Order Functions

New to D Language here. I'm trying to use higher-order functions (i.e. fold!, reduce!, filter!, map!) to create duplicates of array elements. I'm declaring my generic function as pure and trying to accomplish this task as a one line function. The closest I've come so far is
auto dupList(T)(T[] list) pure { (return map!(a => a.repeat(2)); }
but this gives me the following output
[[1,1],[2,2]]
instead of what I'm actually wanting
[1, 1, 2, 2]
I'm calling the function like so
writeln(dupList(nums));
Instead of using map, I've been trying to use reduce in its place but when I switch out map for reduce I get the following errors:
Error instantiated from here: `staticMap!(ReduceSeedType, __lambda2)` C:\D\dmd2\src\phobos\std\algorithm\iteration.d 3287
Error: template `D_Programs.duplist!int.duplist.__lambda2` cannot deduce function from argument types `!()(int, int)`, candidates are: C:\D\dmd2\src\phobos\std\algorithm\iteration.d 3696
Error: template instance `D_Programs.duplist!int.duplist.F!(__lambda2)` error instantiating C:\D\dmd2\src\phobos\std\meta.d 803
Error instantiated from here: `reduce!(int[])` D_Programs.d (refers to dupList)
Error `D_Programs.duplist!int.duplist.__lambda2` D_Programs.d (refers to dupList)
Error instantiated from here: `duplist!int` D_Programs.d (refers to where I'm calling from)
Any help/advice on understanding at least the top three errors and where I'm going wrong with my function would be appreciated.
map essentially replaces each element with the result of calling the passed function on that element. Since your function returns an array of two ints, the result will be an array of arrays, each element holding two ints.
Armed with this knowledge, we can use std.algorith.iteration.joiner:
auto dupList(T)(T[] list) pure { return list.map!(a => a.repeat(2)).joiner; }
As you note, it should also be possible to use reduce, but it's a bit more complicated:
auto dupList(T)(T[] list) pure { return reduce!((a,b) => a~b~b)((T[]).init, list); }
The reasons it's more complicated are:
1) reduce's function takes two arguments - the result of reducing thus far, and the next element.
2) reduce assumes the first element of the passed array is the starting point for reduction, unless a seed value is passed. Since the first element is a T, not a T[], we will need to pass a seed value. [] won't do, since it's typed as void[], so we will need to create an empty T[]. This can be done either with new T[0], or as above, (T[]).init.
Hope this helps - if there are any more questions, please ask! :)
I am assuming you meant to call map!(a => a.repeat(2))(list) or list.map!(a=>a.repeat(2)) (both are the same) since if you don't pass the actual list to the function, it isn't ever actually being called!
Anyway, neither map nor reduce will do what you want on their own. Map transforms individual elements, but can neither add nor remove elements. Reduce (and btw fold, they are basically the same) runs through the array and... well, reduces it down to just one element, like a sum function turning the array 1,2,3 into the single element, 6. Since you want to add elements, you are going to need something else outside.
But first, a sidestep: your call to reduce is failing to compile because it is being passed incorrect arguments (or something, tbh the error messages are really bad and hard to read without having the code they directly refer to open too, but it definitely refers to a lambda). Passing it your dupList won't work because dupList takes an array, but reduce works with just two elements at a time, for example, sum(a, b).
Anyway, back to the main point, the closest you can get is perhaps running another function outside map to flatten the resulting array, or in other words, join them together. There's a function for that: http://dpldocs.info/experimental-docs/std.algorithm.iteration.joiner.2.html
Suggesting a possible answer:
return list .map!(a => a.repeat(2)) .joiner;
BTW: one line functions are grossly overrated. You are often better off writing it on multiple lines, even if as a single statement, if nothing else but so you can get unique line numbers on the error messages. I would prefer to write this out probably something like this:
return
list
.map!(a => a.repeat(2))
.joiner
;
so each line represents a single step of the process. The exact formatting, of course, is up to you, but I like this more stretched out approach for (slightly) nicer error messages and an easier view when editing to add comments or more stuff before, after, in the middle, whatever.

Get all elements but the first as a separate vector

I'm trying to write a basic command-line program in C++. While the rest of the code probably has problems galore, too, the one I'm facing now is this: I've split the inputted line into pieces, but I can't figure out how to get all but the first so I can pass it down the line as the list of arguments for the command.
If this was Ruby, I'd do something like this, where parts is the array of space-separated arguments for the command:
command = parts[0]
args = parts[1..-1]
where parts is the array of bits that were space-separated.
TL;DR: How can I get all but the first elements of a vector?
If using another type makes it easier, feel free to say as much -- I don't think I'll have that much trouble porting it over.
I've tried using a deque, but I don't want to modify parts, just get pieces of it. I've also searched around on this site, but all of the questions that turn up are either related but solved in a way that I can't use, starts of a really hacky workaround that I'd rather avoid, or totally unrelated.
P.S. I'm not using namespace std, but std:: is a pain to type so I omitted it here. Please do provide it in your answers, where applicable.
P.P.S. I'm just (re)starting at C++ so please provide an explanation along with your answer.
TL;DR: How can I get all but the first elements of a vector?
If you want a vector containing that then do this:
std::vector<int> parts = ...;
std::vector<int> args(parts.begin() + 1, parts.end());
If you want only to access the vector elements then start from parts.begin()+1 until parts.end().
The most idiomatic way would be to use iterators and make your function accept an iterator like this:
template<typename It>
void func(It begin, It end) { ... }
and then you pass your vector as:
func(begin(vector) + 1, end(vector));

Creating a dynamic Prolog list of arguments with the C++ interface

Im trying to create a dynamic list of arguments in a C++ program and call a rule in Prolog using the C++ interface to SWI-Prolog. It's something like this:
//includes
int main
{
// other declarations
PlTerm myVariable;
PlTermv myVector(3), vectorArgs(2);
PlTail myList(myVector[0]);
//Here I want to receive texts from keyboard or otherwise in char* variables
//and store it in "myVector",but I don't know how to do it correctly.
//I think it will not work anyway.
vectorArgs[0]= myVariable;
vectorArgs[1]= myList;
//myRule receives a variable and a list with three interchangeable elements.
PlCall ("myRule",vectorArgs);
//the true program is not so simple XD
cout<<"\nMy Variable: "<<(char *)myVariable<<'\n';
return 0;
}
The result has to be "myVariable" as the first position of "vectorArgs" and "myList" as the second containing a list as "[text1, text2, text3]". I got success using PlCompound to compose the list, but it will not serve as the resulting list is constant, and I need a dynamic list. I mean, the list will change in a loop until the program reaches the end, then at a certain moment can become something like "[text3, text1, text2]".
At certain times it seems that only the first element is present in the list, this is causing malfunction of the program and my rule is failing. I consulted the documentation but it shows a lot more C++ code embedded in Prolog than not, and that's what I'm trying to do, I'm doing queries to the Prolog knowledge base using the list, and performing actions in the C++ program, based on the response contained in "myVariable". Thanks a lot!

Why use tuples instead of objects?

The codebase where I work has an object called Pair where A and B are the types of the first and second values in the Pair. I find this object to be offensive, because it gets used instead of an object with clearly named members. So I find this:
List<Pair<Integer, Integer>> productIds = blah();
// snip many lines and method calls
void doSomething(Pair<Integer, Integer> id) {
Integer productId = id.first();
Integer quantity = id.second();
}
Instead of
class ProductsOrdered {
int productId;
int quantityOrdered;
// accessor methods, etc
}
List<ProductsOrderded> productsOrdered = blah();
Many other uses of the Pair in the codebase are similarly bad-smelling.
I Googled tuples and they seem to be often misunderstood or used in dubious ways. Is there a convincing argument for or against their use? I can appreciate not wanting to create huge class hierarchies but are there realistic codebases where the class hierarchy would explode if tuples weren't used?
First of all, a tuple is quick and easy: instead of writing a class for every time you want to put 2 things together, there's a template that does it for you.
Second of all, they're generic. For example, in C++ the std::map uses an std::pair of key and value. Thus ANY pair can be used, instead of having to make some kind of wrapper class with accessor methods for every permutation of two types.
Finally, they're useful for returning multiple values. There's really no reason to make a class specifically for a function's multiple return values, and they shouldn't be treated as one object if they're unrelated.
To be fair, the code you pasted is a bad use of a pair.
Tuples are used all the time in Python where they are integrated into the language and very useful (they allow multiple return values for starters).
Sometimes, you really just need to pair things and creating a real, honest to god, class is overkill. One the other hand, using tuples when you should really be using a class is just as bad an idea as the reverse.
The code example has a few different smells:
Reinventing the wheel
There is already a tuple available in the framework; the KeyValuePair structure. This is used by the Dictionary class to store pairs, but you can use it anywhere it fits. (Not saying that it fits in this case...)
Making a square wheel
If you have a list of pairs it's better to use the KeyValuePair structure than a class with the same purpose, as it results in less memory allocations.
Hiding the intention
A class with properties clearly shows what the values mean, while a Pair<int,int> class doesn't tell you anything about what the values represent (only that they are probably related somehow). To make the code reasonably self explanatory with a list like that you would have to give the list a very desciptive name, like productIdAndQuantityPairs...
For what its worth, the code in the OP is a mess not because it uses tuples, but because the values in the tuple are too weakly typed. Compare the following:
List<Pair<Integer, Integer>> products_weak = blah1();
List<Pair<Product, Integer>> products_strong = blah2();
I'd get upset too if my dev team were passing around IDs rather than class instances around, because an integer can represent anything.
With that being said, tuples are extremely useful when you use them right:
Tuples exist to group ad hoc values together. They are certainly better than creating excessive numbers of wrapper classes.
Useful alternative to out/ref parameters when you need to return more than one value from a function.
However, tuples in C# make my eyes water. Many languages like OCaml, Python, Haskell, F#, and so on have a special, concise syntax for defining tuples. For example, in F#, the Map module defines a constructor as follows:
val of_list : ('key * 'a) list -> Map<'key,'a>
I can create an instance of a map using:
(* val values : (int * string) list *)
let values =
[1, "US";
2, "Canada";
3, "UK";
4, "Australia";
5, "Slovenia"]
(* val dict : Map<int, string> *)
let dict = Map.of_list values
The equilvalent code in C# is ridicuous:
var values = new Tuple<int, string>[] {
new Tuple<int, string>(1, "US"),
new Tuple<int, string>(2, "Canada"),
new Tuple<int, string>(3, "UK"),
new Tuple<int, string>(4, "Australia"),
new Tuple<int, string>(5, "Slovenia")
}
var dict = new Dictionary<int, string>(values);
I don't believe there is anything wrong with tuples in principle, but C#'s syntax is too cumbersome to get the most use out of them.
It's code reuse. Rather than writing Yet Another Class With Exactly The Same Structure As The Last 5 Tuple-Like Classes We Made, you make... a Tuple class, and use that whenever you need a tuple.
If the only significance of the class is "to store a pair of values", then I'd say using tuples is an obvious idea. I'd say it was a code smell (as much as I hate the term) if you started implementing multiple identical classes just so that you could rename the two members.
This is just prototype-quality code that likely was smashed together and has never been refactored. Not fixing it is just laziness.
The real use for tuples is for generic functionality that really doesn't care what the component parts are, but just operates at the tuple level.
Scala has tuple-valued types, all the way from 2-tuples (Pairs) up to tuples with 20+ elements. See First Steps to Scala (step 9):
val pair = (99, "Luftballons")
println(pair._1)
println(pair._2)
Tuples are useful if you need to bundle together values for some relatively ad hoc purpose. For example, if you have a function that needs to return two fairly unrelated objects, rather than create a new class to hold the two objects, you return a Pair from the function.
I completely agree with other posters that tuples can be misused. If a tuple has any sort of semantics important to your application, you should use a proper class instead.
The obvious example is a coordinate pair (or triple). The labels are irrelevant; using X and Y (and Z) is just a convention. Making them uniform makes it clear that they can be treated in the same way.
Many things have already been mentioned, but I think one should also mention, that there are some programming styles, that differ from OOP and for those tuples are quite useful.
Functional programming languages like Haskell for example don't have classes at all.
If you're doing a Schwartzian transform to sort by a particular key (which is expensive to compute repeatedly), or something like that, a class seems to be a bit overkill:
val transformed = data map {x => (x.expensiveOperation, x)}
val sortedTransformed = transformed sort {(x, y) => x._1 < y._1}
val sorted = sortedTransformed map {case (_, x) => x}
Having a class DataAndKey or whatever seems a bit superfluous here.
Your example was not a good example of a tuple, though, I agree.