替换binary_function

Lui*_*uis 19 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);
    }
};
Run Code Online (Sandbox Code Playgroud)

编辑:我正在以下列方式使用这些功能:

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

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

小智 14

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

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

当C++ 98时代的适配器需要argument_type/etc时,unary_function/binary_function是很有用的帮手.类型定义.鉴于C++ 11的完美转发,decltype等等,这种typedef是不必要的.(并且它们不适用于重载/模板化的函数调用操作符.)即使一个类想要提供这些typedef以实现向后兼容性,它也可以直接执行(以冗长的代价),而不是继承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));
    }
}
};
Run Code Online (Sandbox Code Playgroud)

现在可以推断出类型:

std::max_element(v.begin(), v.end(), absoluteLess<>());
Run Code Online (Sandbox Code Playgroud)


T.C*_*.C. 13

唯一std::binary_function所做的就是为会员类型定义result_type,first_argument_typesecond_argument_type.标准库中唯一使用这些typedef的东西std::not2是1)严格被C++取代std::not_fn,但是很容易被lambda取代,3)在C++ 17中被弃用,可能会被删除在下一个版本中.

无论出于何种原因,如果您需要使用not2遗留绑定器(bind1st/ bind2nd,在C++ 11中已弃用并在C++中删除17),或者遵循该协议的某些古老的第三方,更换是定义typedef直接在你的类中:

using result_type = bool;
using first_argument_type = T;
using second_argument_type = T;
Run Code Online (Sandbox Code Playgroud)

否则,只需删除继承.