替代 std::binary_function

replacement for std::binary_function

std::binary_function is deprecated now and is going to be deleted in . I searched on different publications, but I couldn't find a exact way to replace it. I'd like to know how should I write the following code in 风格。

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

inputoutputstd::vector,在 for 循环中。

std::binary_function 唯一做的就是提供成员类型定义 result_typefirst_argument_typesecond_argument_type。标准库中唯一使用这些 typedef 的是 std::not2,它 1) 被 C++17 std::not_fn 严格取代,2) 很容易被 lambda 替换,3) 在C++17,可能会在下一个修订版中删除。

如果出于某种原因,您需要使用 not2,遗留绑定器(bind1st/bind2nd,均在 C++11 中弃用并在 C++ 中删除17), 或者遵循该协议的一些古老的第三方事物,替代方法是直接在 class:

中定义 typedef
using result_type = bool;
using first_argument_type = T;
using second_argument_type = T;

否则,只需删除继承即可。

首先,我的建议是观看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 were useful helpers when C++98-era adaptors needed argument_type/etc. typedefs. Such typedefs are unnecessary given C++11's perfect forwarding, decltype, and so forth. (And they're inapplicable to overloaded/templated function call operators.) Even if a class wants to provide these typedefs for backwards compatibility, it can do so directly (at a minor cost in verbosity) instead of inheriting from unary_function/binary_function, which is what the Standard itself started doing when these helpers were deprecated.

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

在 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::function

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

Test it online