替换binary_function

时间:2015-10-14 00:15:07

标签: c++ c++11

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

输入和输出是for循环中的向量

4 个答案:

答案 0 :(得分:13)

(0, 0.001) [[ 0.00000000e+00 0.00000000e+00 -1.42857119e-08] [ 0.00000000e+00 0.00000000e+00 -1.42857119e-05]] (1, 0.00125) [[ 0.00000000e+00 9.76562337e-10 -2.00892823e-08] [ 0.00000000e+00 4.10156182e-06 -2.34374957e-05]] (2, 0.0015) [[ 0.00000000e+00 3.02734325e-09 -2.82366021e-08] [ -1.46484351e-07 1.03759748e-05 -3.57561308e-05]] (3, 0.00175) [[ -1.31835916e-10 8.00781113e-09 -4.13295119e-08] [ -6.93054082e-07 2.14355430e-05 -5.38674361e-05]] ... (19, 0.006110558142273646) [[ -2.41150395e-06 1.60094544e-05 -1.55746906e-05] [ -3.78656683e-03 2.36296597e-02 -2.20818279e-02]] 唯一提供的是成员typedef std::binary_functionresult_typefirst_argument_type。标准库中唯一使用这些typedef的是second_argument_type,它被1)严格地被C ++ 17 std::not_fn取代,2)很容易被lambda取代,3)不赞成使用C ++ 17,可能会在下一版本中删除。

如果由于某种原因,您需要使用std::not2,那么遗留绑定器(not2 / bind1st,在C ++ 11中都已弃用,在C ++中已被删除17) ,或者在该协议之后的一些古老的第三方事物,替换是直接在你的类中定义typedef:

bind2nd

否则,只需删除继承。

答案 1 :(得分:12)

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

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

  当C ++ 98时代,

unary_function / binary_function是有用的助手   适配器需要argument_type / etc.类型定义。这样的typedef是   不必要的给定C ++ 11的完美转发,decltype等等。   (并且它们不适用于重载/模板化函数调用   运算符。)即使一个类想要提供这些typedef   向后兼容性,它可以直接兼容(以较低的成本)   verbosity)而不是从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<>());

答案 2 :(得分:0)

我相信您正在寻找std::function

答案 3 :(得分:0)

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