使用自定义比较器模板化自定义容器

Templating a Custom Container with a Custom Comparator

本文关键字:自定义 比较器      更新时间:2023-10-16

我有一个自定义容器,其底层数据结构是std::list。目前,容器被模板化为接受任何数据类型(这里是类的标头(:template <typename T> class square_list .

以下是我尝试通过的单元测试的示例:

template <class T> class RuntimeCmp
{
    public:
       enum cmp_mode { normal, reverse };
    private:
       cmp_mode mode;
    public:
       RuntimeCmp( cmp_mode m = normal ) : mode(m) { }
       bool operator()(T const& t1, T const& t2) const { return mode == normal ? t1 < t2 : t2 < t1; }
       bool operator==( RuntimeCmp const& rc ) { return mode == rc.mode; }
};
BOOST_AUTO_TEST_CASE( ut_ctor_compare_passed ) {
     RuntimeCmp<double> rc(RuntimeCmp<double>::reverse);
     square_list<double,RuntimeCmp<double>> s(rc);
     vector<double> data = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    for (auto x : data)
        s.insert(x);
    BOOST_CHECK( std::equal( s.begin(), s.end(), data.rbegin() ) );
}

所以我的问题是,我是否需要在现有容器内创建一个新的结构/类,以便向此自定义比较器的容器添加新的模板参数,以及我是否需要添加一个构造函数,以便我可以像在单元测试中一样将此比较器的参数传递给我的容器?有什么例子可以做类似的事情吗?或者至少只是让模板工作?

我是否需要在现有容器内创建一个新的结构/类,以便为此自定义比较器向我的容器添加新的模板参数

我不确定您所说的"创建新结构/类"是什么意思。要添加新的模板参数,您只需...添加新的模板参数:

template<typename T, typename Cmp> class square_list;

我是否需要添加一个构造函数,以便我可以像在单元测试中一样将此比较器的参数传递给我的容器?

是的,当然。如果要使用比较器类型的参数构造它,则需要一个合适的构造函数。

template<typename T, typename Cmp>
  class square_list
  {
  public:
    square_list(const Cmp&);
    // ...
  };

您将需要一个成员变量来存储比较器:

template<typename T, typename Cmp>
  class square_list
  {
  public:
    square_list(const Cmp& cmp) : m_cmp(cmp)
    { }
  private:
    Cmp m_cmp;
  };

我很难理解你的问题,但也许回顾一下std::set的声明和构造函数会澄清你的困惑。 这是一个听起来有点像你的容器,它包含一种类型的数据,并使用比较器对象对它们进行排序。

template<
    class Key,
    class Compare = std::less<Key>,
    class Allocator = std::allocator<std::pair<const Key, T> >
> class set;
set();
explicit set( const Compare& comp, const Allocator& alloc = Allocator() );
template< class InputIt >
set( InputIt first, InputIt last, 
    const Compare& comp = Compare(), 
    const Allocator& alloc = Allocator() );
template< class InputIt >
set( InputIt first, InputIt last, const Allocator& alloc = Allocator() );
set( const set& other );
set( const set& other, const Allocator& alloc );
set( set&& other );
set( set&& other, const Allocator& alloc );
set( std::initializer_list<value_type> init, 
    const Compare& comp = Compare(), 
    const Allocator& alloc = Allocator() );
set( std::initializer_list<value_type> init, const Allocator& alloc = Allocator() );

并且您必须确保将Compare comp;作为成员存储在类中。 (实际上有一个"更好"的方法,但它很棘手,所以从让它作为普通成员开始。

来源: http://en.cppreference.com/w/cpp/container/set/set