使用C ++中的自定义比较函数初始化多集

时间:2013-09-10 11:57:35

标签: c++ decltype multiset

考虑以下比较功能:

bool compare(std::shared_ptr<myObject> &lhs, std::shared_ptr<myObject> &rhs){
   return lhs->value < rhs->value;
}

现在的想法是初始化一个类型std::shared_ptr<myObject>的多集合,它对具有上述功能的元素进行排序。所以从我读过的书中应该这样做:

std::multiset<std::shared_ptr<myObject>, decltype(compare)*> myset{compare};

问题:

我的问题是,在声明中我传递了一个函数指针来传递比较函数,但为什么我们用{compare} ??来启动集合?它的重要性是什么?为什么有必要这样做?

4 个答案:

答案 0 :(得分:8)

因为该集需要使用比较函子。如果您没有指定一个,它将构成一个默认构造的。在这种情况下,由于您使用的是函数指针类型,因此默认构造的类型将是空指针,无法调用;所以相反,你必须在运行时提供正确的函数指针。

更好的方法可能是使用函数类类型(a.k.a. functor类型);然后可以在编译时解析函数调用,并且默认构造的对象将做正确的事情:

struct compare {
    bool operator()(std::shared_ptr<myObject> &lhs, 
                    std::shared_ptr<myObject> &rhs) const {
        return lhs->value < rhs->value;
    }
};

std::multiset<std::shared_ptr<myObject>, compare> myset;

答案 1 :(得分:2)

要访问您的元素,您需要为您的类型提供strict weak ordering的功能。

std::multiset具有以下构造函数:

 explicit multiset (const key_compare& comp = key_compare(),
               const allocator_type& alloc = allocator_type());

如您所见,您可以通过将comp函数指针(或函数对象)传递给构造函数来完成此操作。


答案 2 :(得分:1)

传递给模板的比较器必须是可以使用函数调用操作符调用的类型。这可能是一个重载了该运算符的类,或者是lambda或函数指针的类型。在set的cunstrutor中,必须传递该类型的实例。所以decltype(compare)*是函数指针类型,&compare是函数指针。

答案 3 :(得分:1)

template参数中的

decltype(compare)*指定比较器的类型。它没有告诉使用哪个函数 - 无论是comparefoobar还是其他。因此构造函数参数。