10

考虑以下比较函数:

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

4 回答 4

12

因为该集合需要一个比较函子才能使用。如果您不指定一个,它将生成一个默认构造的。在这种情况下,由于您使用的是函数指针类型,因此默认构造的将是一个空指针,它不能被调用;因此,您必须在运行时提供正确的函数指针。

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

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;
于 2013-09-10T12:03:46.830 回答
2

decltype(compare)*在模板参数中指定了比较器的类型。它不告诉要使用哪个函数——它是,compare还是别的什么。因此构造函数参数。foobar

于 2013-09-10T12:03:28.800 回答
2

为了访问您的元素,您需要为您的类型提供严格的弱排序功能。

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

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

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


于 2013-09-10T12:04:53.940 回答
1

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

于 2013-09-10T12:03:14.400 回答