简体   繁体   English

STL中使用的C ++自定义比较类型(函数谓词与较少结构)

[英]C++ custom Compare types used in STL (function predicate vs. less struct)

I've check the prototype of std::sort and std::priority_queue, the custom Compare type defined in the template looks quite the same. 我已经检查了std :: sort和std :: priority_queue的原型,模板中定义的自定义Compare类型看起来完全一样。

template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );

template <class T, class Container = vector<T>,
  class Compare = less<typename Container::value_type> > class priority_queue;

But actually they differ, std::sort accepts a function predicate, while std::priority_queue accepts a struct(a type). 但是实际上它们是不同的,std :: sort接受函数谓词,而std :: priority_queue接受struct(类型)。 Why? 为什么? Thanks in advance!. 提前致谢!。

struct cmp {
    bool operator() (const int &a, const int &b) {
        return a < b;
    }
};

vector<int> v;
v.push_back(2);
v.push_back(3);
v.push_back(1);
// this works
sort(v.begin(), v.end(), [](const int &a, const int &b) -> bool {
    return a < b;
});
// this not works
// sort(v.begin(), v.end(), cmp);
cout << v[0] << endl;

// this works
priority_queue<int, cmp> q;
// this not works
// priority_queue<int, [](const int &a, const int &b) -> bool {
//     return a < b;
// }> q;
q.push(2);
q.push(3);
q.push(1);
cout << q.top() << endl;

The difference is that sort is a function template and thus the template argument for Comparator can be deduced from the type of the function argument. 区别在于sort函数模板,因此可以从函数参数的类型推导Comparator模板参数。 When you call it like this: 当您这样称呼它时:

sort(v.begin(), v.end(), [](const int &a, const int &b) -> bool {
    return a < b;
});

then the argument for Comparator is deduced to be the type of the lambda closure object. 然后推导Comparator的参数为lambda闭包对象的类型

priority_queue , on the other hand, is a class template. 另一方面, priority_queue是一个模板。 There's no type deduction. 没有类型推断。 You specify the template argument for Compare in the type of q , and afterwards, you can only supply a function argument (to the constructor) of the appropriate type. 您可以使用q的类型为Compare指定模板参数,然后,您只能提供适当类型的函数参数(给构造函数)。

To use a lambda with a priority queue, you'd need to get hold of its type: 要将lambda与优先级队列一起使用,您需要掌握其类型:

auto compare = [](const int &a, const int &b) -> bool {
  return a < b;
};

std::priority_queue<int, std::vector<int>, decltype(compare)> q(compare);

You were trying to pass a lambda expression as an argument to a template type parameter. 您试图将lambda 表达式作为参数传递给模板类型参数。 This can't work. 这行不通。 Doing the same with sort wouldn't work either: sort做同样的事情也不起作用:

sort<vector<int>::iterator, [](const int &a, const int &b) -> bool {
    return a < b;
}>(/*...*/);

They are actually the same, the difference is in that one is a class template and the other a function template. 它们实际上是相同的,区别在于一个是类模板,另一个是函数模板。

Here's what you can do with the priority queue: 您可以使用优先级队列执行以下操作:

auto comp = [](const int& a, const int& b) { return a < b; };
priority_queue<int, std::vector<int>, decltype(comp)> q(comp);

The difference is that for function templates, the compiler will deduce template parameters from the function parameters supplied, while it won't do that for class templates. 区别在于,对于函数模板,编译器将从提供的函数参数中推断出模板参数,而对于类模板则不这样做。 So you have to supply the type explicitly, and with a lambda (which has an anonymous type), this is annoying. 因此,您必须显式提供该类型,并使用lambda(具有匿名类型),这很烦人。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM