ptr_fun with a lambda function

ptr_fun with a lambda function

本文关键字:lambda function with fun ptr      更新时间:2023-10-16

我有下面的程序,它使用ptr_fun和lambda函数。

#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <cstring>
using namespace std;
int main()
{
    string target="aa";
    vector<string> v1;
    v1.push_back("aa");
    v1.push_back("bb");
    auto stringcasecmp=[](string lhs, string rhs)->int
    {
        return strcasecmp(lhs.c_str(), rhs.c_str());
    };
    auto pos = find_if(
        v1.begin(), v1.end(),
        not1( bind2nd(ptr_fun(stringcasecmp), target) )
        );
    if ( pos != v1.end())
    cout <<   "The search for `" << target << "' was successful.n"
        "The next string is: `" << pos[1] << "'.n";
}

我得到以下错误信息:

stackoverflow.cpp: In function ‘int main()’:
stackoverflow.cpp:21:41: error: no matching function for call to ‘ptr_fun(main()::<lambda(std::string, std::string)>&)’
stackoverflow.cpp:22:6: error: unable to deduce ‘auto’ from ‘<expression error>’

我如何修改代码(最低限度),使其编译?

bind2nd(§D.9)和ptr_fun(§D.8.2.1)在c++ 11中已弃用。您可以在find_if中编写另一个lambda函数:

auto pos = find_if(v1.begin(), v1.end(),
                   [&](const std::string& s) {
                        return !stringcasecmp(s, target); 
                   });

ptr_fun(<lambda>)将不起作用,因为ptr_fun是为c++ 03设计的,用于将函数指针转换为其他适配器的函数对象。lambda已经是一个函数对象,所以ptr_fun是不必要的。

bind2nd期望函数对象定义成员second_argument_typeresult_type,这对于lambda来说不是真的,所以写bind2nd(<lambda>, target)也不能工作。但是在c++ 11中有一个通用的替换:

std::bind(stringcasecmp, std::placeholders::_1, target)

但是,bind没有返回not1期望的c++ 03风格的函数对象:它需要bind的result类型来定义不存在的argument_type成员。因此最后的表达式

std::not1(std::bind(stringcasecmp, std::placeholders::_1, target))

工作。最简单的解决方法是使用我上面写的另一个lambda。

或者,您可以定义一个泛型否定子:

template <typename Predicate>
struct generic_negate
{
    explicit generic_negate(Predicate pred) : _pred(pred) {}
    template <typename... Args>
    bool operator()(Args&&... args)
    {
        return !_pred(std::forward<Args>(args)...);
    }
private:
    Predicate _pred;
};
template <class Predicate>
generic_negate<Predicate> not_(Predicate pred)
{
    return generic_negate<Predicate>(pred);
}
....
auto pos = find_if(v1.begin(), v1.end(), not_(bind(stringcasecmp, _1, target)));

示例:http://ideone.com/6dktf

尝试用pointer_to_binary_function<string,string,int>(stringcasecmp)代替ptr_fun(stringcasecmp) ?