描述你的问题
这是c++ primer 的一道习题,练习10.24,其中有一行代码
auto predicate = [&](int i){ return bind(check_size, str, i)(); };
这行lambda表达式中为什么要在bind()后面多增添一个括号?若不添括号则报错
贴上相关代码(不添括号的情况下)
auto check_size(string const& str, size_t sz){
return str.size() < sz;
}
auto find_first_greater(vector<int> const& v, string const& str){
auto predicate = [&](int i){ return bind(check_size, str, i); };
return find_if(v.cbegin(), v.cend(), predicate);
}
贴上报错信息
严重性 代码 说明 项目 文件 行
错误 C2451 “std::_Binder<std::_Unforced,bool (__cdecl &)(const std::string &,size_t),const std::string &,int &>”类型的条件表达式是非法的 ConsoleApplication5 c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm 43
贴上相关截图
大家讲道理2017-04-17 13:25:06
auto predicate = [&](int i){ return bind(check_size, str, i)(); };
Because the return
statement within the curly braces of lambda needs to return a bool
, bind(...)
returns a callable, and bind(...)()
calls the returned callable, thus returning a bool
.
Personally, I think it is enough to use std::bind
or lambda alone, but the questioner used lambda to package std::bind
once. The purpose of using std::bind
or lambda is to wrap a function that requires multiple parameters into a function with only one parameter, so that it can be used in the parameters of various standard library algorithm functions that require unary predicate.
The code can be found here. The usage of std::bind
is shown in the following fragment:
bool check_size(const std::string &s, std::string::size_type sz) {
return s.size() >= sz;
}
bool check_size_v2(const std::string &s, int sz) {
return sz >= 0 && !check_size(s, sz);
}
std::vector<int>::iterator
findLarger(std::vector<int> &vi, const std::string &s) {
auto it = std::find_if(vi.begin(), vi.end(),
std::bind(check_size_v2, s, std::placeholders::_1)); // <--- 看这里
return it;
}
Specifically, the third parameter of std::find_if
requires an unary predicate. std::bind
is a function adapter, which returns a callable object, and this callable object requires only one parameter (only one placeholder, the rest of the parameters are provided). So it can be used in the third parameter position of std::find_if
.
PHP中文网2017-04-17 13:25:06
bind(check_size, str, i)
I am also a beginner, please correct me if I am wrong.
This thing is a callable object. If you want to return a bool, but you return this, an error will definitely be reported when used in find_if.
bind(check_size, str, i)()
This is equivalent to calling this callable object, and what you get is a bool value.
Also, I think auto is a bit abused?
PHP中文网2017-04-17 13:25:06
auto check_size(string const& str, size_t sz){
return str.size() < sz;
}
auto find_first_greater(vector<int> const& v, string const& str){
//predicate要作为一个函数对象来使用
//bind了之后是一个类似函数对象的东西,要调用才会返回值
auto predicate = [&](int i){ return bind(check_size, str, i)();/*此处要返回 '值'*/ };
return find_if(v.cbegin(), v.cend(), predicate);
}
The above and below are the same effect, and auto means that you don’t need to write the return type. This writing may require a version after c++11 to support it
auto check_size(string const& str, size_t sz) -> bool {
return str.size() < sz;
}
vector<int>::const_iterator find_first_greater(vector<int> const& v, string const& str) {
//predicate要作为一个函数对象来使用
//bind了之后是一个类似函数对象的东西,要调用才会返回值
auto predicate = [&](int i){ return check_size(str, i);/*此处要返回 '值'*/ };
return find_if(v.cbegin(), v.cend(), predicate);
}