replacement for std::binary_function

replacement for std::binary_function

本文关键字:function binary replacement std for      更新时间:2023-10-16

std::binary_function现在已弃用,将在c++17中删除。我搜索了不同的出版物,但我找不到一个确切的替代方法。我想知道我应该如何用c++11风格写下面的代码。

template <class T>
inline T absolute(const T &x) {
    return (x >= 0) ? x : -x;
}
template <class T>
struct absoluteLess : public std::binary_function<T, T, bool> {
    bool operator()(const T &x, const T &y) const {
        return absolute(x) < absolute(y);
    }
};
template <class T>
struct absoluteGreater : public std::binary_function<T, T, bool> {
    bool operator()(T &x, T &y) const {
        return absolute(x) > absolute(y);
    }
};

编辑

我以以下方式使用这些函数:

output[j] = *std::max_element(input.begin() + prev,
                              input.begin() + pos,
                              absoluteLess<float>());

inputoutput为for循环中的std::vector s。

首先,我的建议是观看CppCon 2015: Stephan T. Lavavej"functional: What's New, And Proper Usage"。std::binary_function在幻灯片36上被提到,在视频中大约36分钟。你可以在github.com/CppCon/CppCon2015上找到幻灯片)。它没有详细说明为什么不应该使用std::binary_function,但如果您正在使用自c++ 11以来已弃用的东西,那么您可能会从观看它中受益。

如果您想知道不使用它的实际理由,请尝试n4190:

unary_function/binary_function在c++ 98时代是非常有用的辅助工具需要的适配器参数类型/等等。类型定义。这样的类型是鉴于c++ 11完美的转发、decltype等特性,这是不必要的。它们不适用于重载/模板化的函数调用运营商)。即使一个类想要提供这些类型向后兼容性,它可以直接做到这一点(以很小的代价)冗长)而不是从unary_function/binary_function继承,这是标准本身开始做的事情,当这些助手被弃用。

现在你根本不需要它了,所以你可以从你的程序中删除它的所有痕迹。

在c++ 14中,增加了透明比较器。但它可以在c++ 11中实现。为void专门化:

template<>
struct absoluteLess<void> {
    template< class T, class U>
    constexpr auto operator()( T&& lhs, U&& rhs ) const
      -> decltype(absolute(std::forward<T>(lhs)) < absolute(std::forward<U>(rhs)))
    {
        return absolute(std::forward<T>(lhs)) < absolute(std::forward<U>(rhs));
    }
}
};

现在可以推导出类型:

std::max_element(v.begin(), v.end(), absoluteLess<>());

std::binary_function所做的唯一事情是提供成员类型result_typefirst_argument_typesecond_argument_type。标准库中唯一使用这些类型的是std::not2,它1)被c++ 17 std::not_fn严格取代,2)无论如何都很容易被lambda取代,3)在c++ 17中已弃用,很可能在下一个版本中被删除。

如果,无论出于何种原因,您需要使用not2,遗留绑定(bind1st/bind2nd,在c++ 11中已弃用,在c++ 17中已删除),或遵循该协议的一些古老的第三方东西,替换方法是直接在类中定义类型:

using result_type = bool;
using first_argument_type = T;
using second_argument_type = T;

binary_function可以很容易地被lambda函数代替:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
// Lambdas can be declared in the global scope
auto absolute = [](auto& x)->float{ return x<0?-x:x;};
int main()
{
    // Lambdas can be declared embedded in functions
    auto absoluteLess = [&](auto&x, auto&y)->bool{ return absolute(x)>absolute(y);};
    auto absoluteGreater = [&](auto&x, auto&y)->bool{ return absolute(x)<absolute(y);};
    
    std::vector<float> input={-2.0, 0.0, 3.4, -123.0};
    std::cout <<  *std::max_element(input.begin(), input.end(), absoluteLess) <<std::endl;
    std::cout <<  *std::max_element(input.begin(), input.end(), absoluteGreater) <<std::endl;
    return 0;
}

在线测试

我相信你在找std::function