【问题标题】:C++/STL Default comparatorC++/STL 默认比较器
【发布时间】:2013-07-13 05:31:24
【问题描述】:

我正在编写一个模板函数,它接受一个元素向量并对其进行一系列操作。其中一项操作是 std::sort()。

当然,客户端代码需要提供一个比较函子。如果客户端代码传入已知类型(整数、字符串等)的容器,我不希望客户端代码为此参数指定值。我应该如何定义我的 Comp 模板参数的默认值?

template<typename Container, typename Comp=????>
void my_func(Container elements, Comp comp) {
  ...
  std::sort(elements.begin(), elements.end(), comp);
  ...
}

【问题讨论】:

  • 请注意,std::sortstd::list 上可能效率不高;因此std::list 有一个.sort 成员函数。
  • 你的代码打错了,你写的是“typenam Container”,应该是“typename”

标签: c++ stl


【解决方案1】:

std::sort 使用“Less”作为默认比较器。所以要保持一致:

template<typename Container, typename Comp = std::less<typename Container::value_type> >
void my_func(Container& elements, Comp comp = Comp())
{
  std::sort(elements.begin(), elements.end(), comp);
}

【讨论】:

    【解决方案2】:
    #include <vector>
    #include <algorithm>
    
    template<typename Container, typename Comp=std::less<typename Container::value_type>>
    void my_func(Container elements, Comp comp = Comp()) {
      //...
      std::sort(elements.begin(), elements.end(), comp);
      //...
    }
    
    int main() {
        std::vector<int> v;
        my_func(v);
    }
    

    另请注意Comp comp = Comp()

    【讨论】:

      【解决方案3】:

      我不会默认模板本身,而是将函数的参数默认为类似于std::greaterstd::less&gt;&lt;std::sort 默认使用std::less

      如果你想获得它的模板参数,那么有一个建议是让std::greater&lt;&gt; 用于称为N3421 的通用类型,它实际上已被 C++14 接受。

      但是在那之前你可以做std::greater&lt;typename Container::value_type&gt;。如果愿意,您可以选择使用 type_traits 删除引用或 cv 限定符。

      &lt;functional&gt; 有其他默认比较,但这两个是最常见的。

      所以一个“完整”的解决方案应该是这样的:

      template<typename Container, typename Comp>
      void my_func(Container& elements, Comp comp = std::less<typename Container::value_type>()) {
        std::sort(elements.begin(), elements.end(), comp);
      }
      

      【讨论】:

        【解决方案4】:

        在您的示例中有两个问题:

        1. 要实现默认行为,您必须提供 less&lt;T&gt; 作为仿函数。

        2. 您的函数正在获取副本,因此,副本将被排序,除非您改为引用Container

        示例如何制作:

        #include <functional>
        template<typename Container, typename Comp=std::less<typename Container::value_type> >
        void my_func(Container &elements, Comp comp = Comp() )
        {
          std::sort(elements.begin(), elements.end(), comp);
        }
        // A partial specialisation for std::list
        #include <list>
        template<typename ContainerValueType, typename Allocator, typename Comp=std::less<ContainerValueType> >
        void my_func(std::list<ContainerValueType, Allocator> &elements, Comp comp = Comp() )
        {
          elements.sort(comp);
        }
        

        【讨论】:

        • +1 是唯一一个纠正传递值问题的人。
        猜你喜欢
        • 1970-01-01
        • 2012-11-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-07
        • 1970-01-01
        相关资源
        最近更新 更多