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

时间:2014-08-12 19:10:55

标签: c++ boost

我有一个自定义容器,其底层数据结构是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() ) );
}

所以我的问题是,我是否需要在现有容器中创建一个新的struct / class,以便为我的容器添加一个新的模板参数以用于此自定义比较器并且我是否需要添加一个构造函数以便我可以如同单元测试一样,将这个比较器的参数传递给我的容器?有关如何做到这一点的任何例子?或者至少只是让模板工作?

2 个答案:

答案 0 :(得分:3)

  

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

我不确定你的意思&#34;创建一个新的结构/类&#34;。要添加新模板参数,您只需...添加新模板参数:

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;
  };

答案 1 :(得分:2)

我无法理解您的问题,但是对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