search

Home  >  Q&A  >  body text

c++中关于lambda表达式和bind函数的问题?

  1. 描述你的问题
    这是c++ primer 的一道习题,练习10.24,其中有一行代码

auto predicate = [&](int i){ return bind(check_size, str, i)(); };

这行lambda表达式中为什么要在bind()后面多增添一个括号?若不添括号则报错

  1. 贴上相关代码(不添括号的情况下)

    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);

    }

  2. 贴上报错信息
    严重性 代码 说明 项目 文件 行

错误 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

  1. 贴上相关截图

巴扎黑巴扎黑2803 days ago698

reply all(3)I'll reply

  • 大家讲道理

    大家讲道理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.

    reply
    0
  • PHP中文网

    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?

    reply
    0
  • PHP中文网

    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);
    }

    reply
    0
  • Cancelreply