C ++动态分配std :: map比较器

时间:2015-03-10 02:13:37

标签: c++ c++11 dynamic comparator stdmap

所以我有两个包含std :: map成员的类,它们的功能实际上相同,只是一个map的顺序是std :: less而另一个是std :: greater。

如果我创建一个抽象父类并声明一个map成员,有没有办法在派生类构造函数中为该成员动态分配比较器?这样,功能显然都可以驻留在父类中。

3 个答案:

答案 0 :(得分:3)

事后你不能改变比较器。但是你可以使用相同的比较器类并获得更高的"更高的"或者"较少"在施工时。你只需要一个有状态的比较器:

struct my_compare {
    enum compare_type { less, greater };
    explicit my_compare(compare_type t) : m_type(t) {}
    template<class T, class U>
    bool operator()(const T& t, const U& u) const {
        if(m_type == less) { return t < u; }
        else { return t > u; }
    }
    compare_type m_type;
};

然后你可以做

std::map<int, int, my_compare> less_map((my_compare(my_compare::less)));
std::map<int, int, my_compare> greater_map((my_compare(my_compare::greater)));

额外的一对括号是因为it would otherwise be the most vexing parse , even though a function parameter declaration cannot have a qualified name。在C ++ 11中,可以使用列表初始化(my_compare{mycompare::less})。


对于您的特定设计,实现可能看起来像

class A {
protected:
    explicit A(my_compare::compare_type ct) : my_map(my_compare(ct)) {}
    std::map<int, int, my_compare> my_map;
};

class B_less : public A{
public:
    B_less() : A(my_compare::less) {}
};

答案 1 :(得分:1)

没有。比较函数用于生成实际的数据结构 - 更改比较函数需要从头开始重建结构。

也就是说,如果您只想以相反的顺序迭代结构,map是一个可逆容器,那么您可以使用反向迭代器正常循环结构。

答案 2 :(得分:1)

您可以通过创建根据某种状态使用更少或更多的自定义仿函数类来执行您想要执行的操作。这是一个例子:

#include <iostream>
#include <string>
#include <map>

struct MyCompare
{
   MyCompare(bool useLess) : useLess_(useLess) {}

   bool operator()(int lhs, int rhs)
   {
      if ( useLess_ )
      {
         return (lhs < rhs);
      }
      else
      {
         return (lhs > rhs);
      }
   }
   bool useLess_;
};

int main(int argc, char** argv)
{
   std::map<int, std::string, MyCompare> myMap1(MyCompare(true));
   std::map<int, std::string, MyCompare> myMap2(MyCompare(false));

   myMap1[1] = "abcd";
   myMap1[2] = "lmnop";
   myMap1[3] = "xyz";

   myMap2[1] = "abcd";
   myMap2[2] = "lmnop";
   myMap2[3] = "xyz";

   std::cout << "Map 1: " << std::endl; for ( auto const& v : myMap1 )
   {
      std::cout << "Key: " << v.first << ", Value: " << v.second << std::endl;
   }

   std::cout << "Map 2: " << std::endl;
   for ( auto const& v : myMap2 )
   {
      std::cout << "Key: " << v.first << ", Value: " << v.second << std::endl;
   }

   return 0;
}

输出:

Map 1: 
Key: 1, Value: abcd
Key: 2, Value: lmnop
Key: 3, Value: xyz
Map 2: 
Key: 3, Value: xyz
Key: 2, Value: lmnop
Key: 1, Value: abcd

在您的情况下,您可以将子类中的标志传递给父类,以指示用于创建比较仿函数的值。