简体   繁体   English

带有lambda函数的ptr_fun

[英]ptr_fun with a lambda function

I have the following program that uses ptr_fun with a lambda function. 我有以下程序使用带有lambda函数的ptr_fun。

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

I get the following error messages. 我收到以下错误消息。

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>’

How do i amend the code (minimally) to make it compile? 我如何修改代码(最低限度)使其编译?

bind2nd (§D.9) and ptr_fun (§D.8.2.1) are deprecated in C++11. 在C ++ 11中不推荐使用bind2nd (§D.9)和ptr_fun (§D.8.2.1)。 You could just write another lambda function in find_if : 你可以在find_if编写另一个lambda函数:

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

ptr_fun(<lambda>) will not work, because ptr_fun is designed for C++03 to convert a function pointer to a function object for other adaptors. ptr_fun(<lambda>)将不起作用,因为ptr_fun是为C ++ 03设计的,用于将函数指针转换为其他适配器的函数对象。 A lambda is already a function object, so the ptr_fun is unnecessary. lambda已经是一个函数对象,所以ptr_fun是不必要的。

bind2nd expects the function object to define the members second_argument_type and result_type , which is not true for a lambda, so writing bind2nd(<lambda>, target) won't work either. bind2nd期望函数对象定义成员second_argument_typeresult_type ,这对于lambda是不正确的,因此编写bind2nd(<lambda>, target)也不起作用。 But in C++11 there is a generic replacement that works: 但在C ++ 11中,有一个通用的替代品可以工作:

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

However, bind does not return a C++03-style function object, which not1 is expecting: it requires the type of result of bind to define the argument_type member which does not exist. 但是, bind不会返回C ++ 03样式的函数对象,而not1期望它:它需要bind的结果类型来定义不存在的argument_type成员。 Therefore the final expression 因此最后的表达

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

will not work. 不行 The simplest workaround is just use another lambda I've written above. 最简单的解决方法是使用我上面写的另一个lambda。

Alternatively, you could define a generic negator: 或者,您可以定义一个通用的否定符:

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

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

尝试使用pointer_to_binary_function<string,string,int>(stringcasecmp)而不是ptr_fun(stringcasecmp)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM