代码之家  ›  专栏  ›  技术社区  ›  Walter

缺少std::maximum的设计考虑是什么?

  •  -6
  • Walter  · 技术社区  · 7 年前

    C++标准库支持各种 function objects ,包括结合二元函子 std::plus std::multiplies ,这是各种 fold 算法,例如 std::accumulate std::reduce ,或 tbb::parallel_reduce .

    我在执行一个 Fenwick tree 将关联二元运算符作为模板参数(默认为 std::plus<void>

    template<typename T=void>
    struct maximum
    {
        constexpr T operator() (T const&x, T const&y) const
        { return x>y? x:y; }
    };
    
    template<>
    struct maximum<void>
    {
        template<typename T>
        constexpr T operator() (T const&x, T const&y) const
        { return x>y? x:y; }
    };
    

    当Fenwick树可以在对数时间内找到任何元素前缀中的最大值,或者在一个元素范围内。

    然而,令我惊讶的是,这种二进制最大函子在标准库中并不存在。当然,我可以使用我自己的代码,但这就不可能专门编写通用代码。例如,更新一个Fenwick树以改变一个元素可以在最大值的情况下进行优化:如果树节点表示的范围内的上一个最大值超过新值,则可以终止树过程。

    那么,有没有什么严重的理由不去 std::maximum std::minimum (除了 )?

    std::max 没有选择 在这里:

    std::accumulate(v.begin(), v.end(), 0, std::max<T>);
    

    不工作(在C++ 11中,但是它以前做过),而不是(使用以上) maximum )

    std::accumulate(v.begin(), v.end(), 0, std::plus<void>{});
    std::accumulate(v.begin(), v.end(), 0, maximum<void>{});
    

    选择 例如,以比较函子作为参数的函子

    template<typename T, typename Compare = std::greater<T> >
    struct select
    {
        constexpr T operator()(T const&x, T const&y) const
        { return comp(x,y)? x:y; }
      private:
        Compare comp;        
    };
    

    select<void> 以类似的方式。

    1 回复  |  直到 7 年前
        1
  •  -1
  •   user9335240    7 年前

    Accumulate是一个模板函数,它只尝试调用accumulator函数,无论它是 Callable 或者是一个正则函数(正则函数本身是可调用的),所以使用它是完全有效的

    cout << std::accumulate(v.begin(), v.end(), 0, std::max<YOUR_TYPE_HERE>);
    

    如果类型复杂(如不适用于MAX的任何东西),则可以传递自定义的lambda表达式(仅C++ 11以下):

    cout << std::accumulate(v.begin(), v.end(), 0, [](int a, int b){return a > b ? a : b;});
    

    int 与你的类型,并替换 return a > b ? a : b;

    如果编译器拒绝编译第一个,并且在C++ 11之前处于某个位置,则可以尝试这行(不安全)

    cout << std::accumulate(v.begin(), v.end(), 0, std::ptr_fun(std::max<int>));
    

    std::ptr_fun 将任何函数转换为函数对象,以便可以使用,请参阅此引用 http://www.cplusplus.com/reference/functional/ptr_fun/

    还有一个类叫做 std::pointer_to_binary_function 那会对你有更大的帮助。这是它的参考 http://www.cplusplus.com/reference/functional/pointer_to_binary_function/