I have a vector of strings and an empty vector of int:
vector<string> ints_as_strings;
vector<int> ints_as_ints;
Goal is to transform the former into the latter.
std::transform with a lambda works:
std::transform(ints_as_strings.begin(),
ints_as_strings.end(),
back_inserter(ints_as_ints),
[](const string& s) {return std::stoi(s);});
However I just want to use std::stoi.
Passing the address of my mystoi function works:
int mystoi(string s) {return stoi(s);}
std::transform(ints_as_strings.begin(),
ints_as_strings.end(),
back_inserter(ints_as_ints),
&mystoi);
However, directly passing the address of std::stoi doesn't work.
Is this on account of the extra parameters (for which, however, default values are provided)?
Related
This is part of an assignment, I am stuck at this instruction:
Sort your randomly generated pool of schedules.
Use std::stable_sort,
passing in an object of type schedule_compare as the custom comparison
operator.
UPDATE: I was checking cppreference stable_srot(), see method definition below:
void stable_sort ( RandomAccessIterator first, RandomAccessIterator
last,Compare comp );
, and it seems from what I understood is that you can only pass functions to the last argument (Compare comp) of the stable_sort() i.e:
However, in the instructions, it says that you need to pass an object of type schedule_compare. How is this possible ?
This is my code below:
struct schedule_compare
{
explicit schedule_compare(runtime_matrix const& m)
: matrix_{m} { }
bool operator()(schedule const& obj1, schedule const& obj2) {
if (obj1.score > obj2.score)
return true;
else
return false;
}
private:
runtime_matrix const& matrix_;
};
auto populate_gene_pool(runtime_matrix const& matrix,
size_t const pool_size, random_generator& gen)
{
std::vector<schedule> v_schedule;
v_schedule.reserve(pool_size);
std::uniform_int_distribution<size_t> dis(0, matrix.machines() - 1);
// 4. Sort your randomly generated pool of schedules. Use
// std::stable_sort, passing in an object of type
// schedule_compare as the custom comparison operator.
std::stable_sort(begin(v_schedule), end(v_schedule), ???)
return; v_schedule;
}
For algorithm functions that accepts a "function" (like std::stable_sort) you can pass anything that can be called as a function.
For example a pointer to a global, namespace or static member function. Or you can pass a function-like object instance (i.e. an instance of a class that has a function call operator), also known as a functor object.
This is simply done by creating a temporary object, and passing it to the std::stable_sort (in your case):
std::stable_sort(begin(v_schedule), end(v_schedule), schedule_compare(matrix));
Since the schedule_compare structure have a function call operator (the operator() member function) it can generally be treated like any other function, including being "called".
I am trying to get more familiar with the C++11 standard by implementing the std::iterator on my own doubly linked list collection and also trying to make my own sort function to sort it.
I would like the sort function to accept a lamba as a way of sorting by making the sort accept a std::function, but it does not compile (I do not know how to implement the move_iterator, hence returning a copy of the collection instead of modifying the passed one).
template <typename _Ty, typename _By>
LinkedList<_Ty> sort(const LinkedList<_Ty>& source, std::function<bool(_By, _By)> pred)
{
LinkedList<_Ty> tmp;
while (tmp.size() != source.size())
{
_Ty suitable;
for (auto& i : source) {
if (pred(suitable, i) == true) {
suitable = i;
}
}
tmp.push_back(suitable);
}
return tmp;
}
Is my definition of the function wrong? If I try to call the function, I recieve a compilation error.
LinkedList<std::string> strings{
"one",
"two",
"long string",
"the longest of them all"
};
auto sortedByLength = sort(strings, [](const std::string& a, const std::string& b){
return a.length() < b.length();
});
Error: no instance of function template "sort" matches the argument
list argument types are: (LinkedList, lambda []bool
(const std::string &a, const std::string &)->bool)
Additional info, the compilation also gives the following error:
Error 1 error C2784: 'LinkedList<_Ty> sort(const
LinkedList<_Ty> &,std::function)' : could not
deduce template argument for 'std::function<bool(_By,_By)>'
Update: I know the sorting algorithm is incorrect and would not do what is wanted, I have no intention in leaving it as is and do not have a problem fixing that, once the declaration is correct.
The problem is that _By used inside std::function like this cannot be deduced from a lambda closure. You'd need to pass in an actual std::function object, and not a lambda. Remember that the type of a lambda expression is an unnamed class type (called the closure type), and not std::function.
What you're doing is a bit like this:
template <class T>
void foo(std::unique_ptr<T> p);
foo(nullptr);
Here, too, there's no way to deduce T from the argument.
How the standard library normally solves this: it does not restrict itself to std::function in any way, and simply makes the type of the predicate its template parameter:
template <typename _Ty, typename _Pred>
LinkedList<_Ty> sort(const LinkedList<_Ty>& source, _Pred pred)
This way, the closure type will be deduced and all is well.
Notice that you don't need std::function at all—that's pretty much only needed if you need to store a functor, or pass it through a runtime interface (not a compiletime one like templates).
Side note: your code is using identifiers which are reserved for the compiler and standard library (identifiers starting with an underscore followed by an uppercase letter). This is not legal in C++, you should avoid such reserved identifiers in your code.
Scott Meyer's Effective STL showed an example of using sorted vector of pair<key, value> to simulate a map or multimap. In order to sort the vector and later look up the elements in the vector, he has to create a functor DataCompare where there are 3 overloaded function operator(): one that takes two pair object for sorting; two that take a pair and a key because in algorithms like lower_bound, equal_range, we don't know the order in which the key object and the pair object are passed to the custom comparison functor:
typedef pair<string, int> Data; // type held in the "map"
class DataCompare { // class for comparison
public:
bool operator()(const Data& lhs, const Data& rhs) const // comparison func for sorting
{
return keyLess(lhs.first, rhs.first);
}
bool operator()(const Data& Ihs, const Data::first_type& k) const // comparison func for lookups
{ //(form 1)
return keyLess(lhs.first, k);
}
bool operator()(const Data::first_type& k, const Data& rhs) const // comparison func for lookups
{ // (form 2)
return keyLessfk, rhs.first);
}
....
Now that we have C++11, we have lambda and std::bind and std::function to replace functors. But how do I use lambda or std::bind or std::function to deal with the uncertainty of the order the arguments are passed in (lookup) algorithms like lower_bound, upper_bound and equal_range?
In http://www.cplusplus.com/reference/algorithm/lower_bound/, the description for comp seems to suggest I can create a lambda whose first parameter can be the pair and the second parameter can be of the same type as key. However, inside the implementation of lower_bound, it can switch the order in calling the lambda. In g++ (my version is 4.8.4), I got the following error:
... else if (__comp(__val, *__middle))
...
no known conversion for argument 1 from ‘const std::basic_string’ to ‘const ms2dict& {aka const std::pair< std::basic_string< char>, std::basic_string< char> >&}’
Here the else if (__comp(__val, *__middle)) is using the lambda but passing the arguments in reverse order. Is there a way to create a universal callable object that deal with this problem?
I would like to achieve the following
#include <iostream>
unsigned foo(int i) {return i;};
unsigned bar(unsigned(*p)()) {/*Do important work*/return p();};
int main(void){
int integer = 42;
auto lambda = [integer] () -> unsigned {return foo(integer);};
unsigned number = bar(lambda);
std::cout << number << std::endl;
}
That is, bar is expecting a pointer to function with no arguments and returning unsigned. I can easily write a wrapper unsigned baz() {return foo(42);};and pass that one to bar(), but this has two drawbacks
it's a separate function, while I would prefer to construct the wrapper inline
I have to write a new wrapper for each expected value of `integer.
The idea is that bar() is doing some work, in the process invoking the function, that was passed to it. I have a suitable function, but it has an extra argument. That extra argument, however, is known at the point of passing the function to bar().
Is there a way to pull this off, or should I forget this approach and use templates? I have control over changing the interface (e.g. change the function pointer argument to std::function).`
C++11 lambdas that does not capture anything can be stored in a function pointer. One just need to ensure that lambda accepts and returns the same parameters as the function pointer.
In GObject library all callbacks has type void(*GCallback) (void). This definition does not anyhow affect signature of the callback though:
The type used for callback functions in structure definitions and
function signatures. This doesn't mean that all callback functions
must take no parameters and return void. The required signature of a
callback function is determined by the context in which is used (e.g.
the signal to which it is connected). Use G_CALLBACK() to cast the
callback function to a GCallback.
In other words, one can pass function like this:
int my_function(int a, char b) {}
by casting its type (that's what G_CALLBACK do):
do_something(G_CALLBACK(my_function));
Unfortunately typecasting does not work with C++11 lambdas:
do_something(G_CALLBACK([](int a, char b) -> int {...});
// Cannot cast from type lambda to pointer type GCallback
Is it possible to use C++ lambdas of arbitrary type in place of GCallback?
UPDATE
Just to clarify, I know that lambda can be casted to a function pointer if their signatures match. My question is in another dimension.
The ISO C standard guarantees that function can be casted forth and back without loosing any precision. In other words one the following expression is valid:
int f(int a){...}
void (*void_f)() = (void (*)())f;
int (*restored_f)(int) = (int (*)(int))void_f;
restored_f(10);
My question is whether the following expression is also valid according to C++11:
int (*f)(int) = [](int a) -> int {};
void (*void_f)() = (void (*)())f;
int (*restored_f)(int) = (int (*)(int))void_f;
restored_f(10);
The following code compiles and works for me (MSVC 2013):
auto lambdaFunc = [](int a, char b) -> int { return 0; };
typedef int (*LambdaType)(int, char);
GCallback fnTest1 = G_CALLBACK((LambdaType)lambdaFunc);
GCallback fnTest2 = G_CALLBACK((LambdaType) [](int a, char b) -> int { return 0; });
do_something(fnTest1);
do_something(fnTest2);
do_something(G_CALLBACK((LambdaType)lambdaFunc));
Lambdas without a capture are implicitly convertible to a pointer to a function by the standard. Though not all compilers support this feature at the moment (https://stackoverflow.com/a/2935230/261217).
Then you can explicitly cast a function pointer to GCallback.