【问题标题】:replacement for std::binary_function替换 std::binary_function
【发布时间】:2015-10-14 00:15:07
【问题描述】:

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

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::vectors,在 for 循环中。

【问题讨论】:

标签: c++17 c++11 c++ c++11 deprecated


【解决方案1】:

首先,我的建议是观看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 时代是有用的助手 适配器需要 argument_type/等。类型定义。这样的 typedef 是 鉴于 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<>());

【讨论】:

    【解决方案2】:

    std::binary_function 唯一做的就是提供成员 typedef 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 中删除),或者一些古老的第三方 -遵循该协议的派对,替代方法是直接在您的类中定义 typedef:

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

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

    【讨论】:

      【解决方案3】:

      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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

        • 如果您在问题的代码中展示了如何实现它会很好。
        • @Dharman:这看起来有点矫枉过正...... std::function 封装了任何行为像函数的东西,带有任意数量的参数。
        猜你喜欢
        • 2014-02-09
        • 2012-10-10
        • 2015-04-02
        • 2023-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-04
        • 2021-09-15
        相关资源
        最近更新 更多