In this example I am supposed to sort a vector of strings depending on a given size, lest's say elements whose length greater than or equal to the given size come first and then the remaining.
So here is what I've done:
bool is_shorter(std::string const& str, std::string::size_type sz){
return !(str.size() < sz);
}
int main(){
std::vector<string> vstr{"vector", "In", "this", "example", "am", "supposed",
"sort", "a", "of", "I", "strings", "depending"};
std::string::size_type len = 5;
// std::sort( vstr.begin(), vstr.end(),
// std::bind(is_shorter, placeholders::_1, len) );
std::sort( vstr.begin(), vstr.end(),
std::bind( [](std::string const& str, std::string::size_type sz){
return !(str.size() < sz);}, std::placeholders::_1, len ) );
for(auto const& str : vstr)
std::cout << str << ", ";
std::cout << '\n';
std::cout << '\n';
}
The output:
depending, strings, supposed, example, vector, In, this, am, sort, a, of, I,
As you can see the program works fine as I expected but what matters and confuses me is how come the comparison operation:
Inside sort
I guess something like this:
comp(*it, *it + 1); // for simplicity sake only. (I mean two elements of the same sequence -of course same type- are passed-in)
Which I mean the comparison operation is a binary operation that is called each iteration for each contiguous elements. Those elements are of the same type (of the elements in the sequence).
So how can std::bind
changes the second parameter to std::string::size_type
rather than std::string
?
How can std::bind
makes the operation takes only one string
? and what happens to the second string
passed in?
Can someone explain to me what happens exactly in std::bind
here?
It doesn't matter me if the lambda passed-in or the custom comparison operation if it takes arguments of the same type:
for example to sort a vector of strings so that the elements that are equal to a given string appear first:
std::sort(vstr.begin(), vstr.end(),
std::bind([](std::string s1, std::string s2 ){ return s1 == s2;}, _1, std::string("vector")
));
Not exactly related, but your answer is wrong: "depending, strings, supposed, example, vector, In, this, am, sort, a, of, I," Note that "In" is before "this" and "sort". Your sorting function should be comparing the sizes of the two input strings.
Now, for the 'How does bind work?'. Basically, when you call std::bind
, it copies/moves all of the additional arguments provided into the returned data structure. This structure has a templated operator()
. The parameters passed to operator()
are substituted in place of the std::placeholders
objects that were provided during the call to bind. The important part here is that any parameters passed during the invocation that are not mentioned are not forwarded to the bound functor.
So in this case, because you didn't pass std::placeholders:_2
to the call to bind, the second argument is discarded. The second argument to the lambda is filled in by len
which you passed in.
There is more functionality in std::bind
, but this covers the simplest use case.