首頁  >  問答  >  主體

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. 贴上相关截图

巴扎黑巴扎黑2765 天前676

全部回覆(3)我來回復

  • 大家讲道理

    大家讲道理2017-04-17 13:25:06

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

    因為lambda 的大括號內的return語句需要回傳的是一個boolbind(...)傳回了一個callable,bind(...)()則是呼叫了這個回傳的callable,從而回傳了一個bool

    個人認為,本來單獨使用std::bind或 lambda 就夠了,題主卻用 lambda 把 std::bind打包了一次。使用std::bind或 lambda 的目的就是為了將一個需要多個參數的函數,包裝成只有一個參數的函數,從而能夠用在各種需要 unary predicate 的標準函式庫的演算法函數的參數中。

    程式碼見這裡。其中std::bind的使用如下述片段所示:

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

    具體來說,std::find_if的第三個參數需要一個 unary predicate。 std::bind是一個 function adapter,它會回傳一個 callable object,而這個 callable object 只需要一個參數(只有一個 placeholder,其餘參數都已提供)。所以可以用在std::find_if的第三個參數的位置。

    回覆
    0
  • PHP中文网

    PHP中文网2017-04-17 13:25:06

    bind(check_size, str, i)
    

    也是初學,有錯請指正哈。
    這個東西是個可調用對象,你想要返回一個 bool,卻返回一個這個,用在 find_if 里肯定會報錯。

    bind(check_size, str, i)() 
    

    這個相當於你呼叫了這個可調用對象,那麼得到的就是 bool 值了。
    另外我覺得是不是 auto 有點被濫用了?

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

    上面和下面是一個效果,還有就是auto不是說你不用寫回類型的,這樣寫可能要c++11之後的版本才能支援

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

    回覆
    0
  • 取消回覆