STL 中使用的 C++ 自定义比较类型(函数谓词与 less 结构)
C++ custom Compare types used in STL (function predicate vs. less struct)
我查看了std::sort和std::priority_queue的原型,模板中定义的自定义比较类型看起来很像。
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;
但实际上它们是不同的,std::sort接受一个函数谓词,而std::priority_queue接受一个结构(一种类型)。 为什么?提前致谢!
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;
其实是一样的,区别是一个是class模板,一个是函数模板。
以下是您可以使用优先级队列执行的操作:
auto comp = [](const int& a, const int& b) { return a < b; };
priority_queue<int, std::vector<int>, decltype(comp)> q(comp);
不同之处在于,对于函数模板,编译器将从提供的函数参数中推导出模板参数,而对于 class 模板则不会。所以你必须明确地提供类型,并且使用 lambda(它有一个匿名类型),这很烦人。
不同之处在于 sort
是一个 function 模板,因此 Comparator
的 template 参数可以从 function 参数的类型推导出来。当你这样称呼它时:
sort(v.begin(), v.end(), [](const int &a, const int &b) -> bool {
return a < b;
});
然后 Comparator
的参数被推断为 lambda 闭包对象的 类型 。
另一方面,priority_queue
是一个 class 模板。没有类型扣除。您在 q
的类型中指定 Compare
的模板参数,之后,您只能提供适当类型的函数参数(给构造函数)。
要将 lambda 与优先级队列一起使用,您需要了解其类型:
auto compare = [](const int &a, const int &b) -> bool {
return a < b;
};
std::priority_queue<int, std::vector<int>, decltype(compare)> q(compare);
您试图将 lambda 表达式 作为参数传递给模板 type 参数。这是行不通的。用 sort
做同样的事情也行不通:
sort<vector<int>::iterator, [](const int &a, const int &b) -> bool {
return a < b;
}>(/*...*/);
我查看了std::sort和std::priority_queue的原型,模板中定义的自定义比较类型看起来很像。
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;
但实际上它们是不同的,std::sort接受一个函数谓词,而std::priority_queue接受一个结构(一种类型)。 为什么?提前致谢!
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;
其实是一样的,区别是一个是class模板,一个是函数模板。
以下是您可以使用优先级队列执行的操作:
auto comp = [](const int& a, const int& b) { return a < b; };
priority_queue<int, std::vector<int>, decltype(comp)> q(comp);
不同之处在于,对于函数模板,编译器将从提供的函数参数中推导出模板参数,而对于 class 模板则不会。所以你必须明确地提供类型,并且使用 lambda(它有一个匿名类型),这很烦人。
不同之处在于 sort
是一个 function 模板,因此 Comparator
的 template 参数可以从 function 参数的类型推导出来。当你这样称呼它时:
sort(v.begin(), v.end(), [](const int &a, const int &b) -> bool {
return a < b;
});
然后 Comparator
的参数被推断为 lambda 闭包对象的 类型 。
priority_queue
是一个 class 模板。没有类型扣除。您在 q
的类型中指定 Compare
的模板参数,之后,您只能提供适当类型的函数参数(给构造函数)。
要将 lambda 与优先级队列一起使用,您需要了解其类型:
auto compare = [](const int &a, const int &b) -> bool {
return a < b;
};
std::priority_queue<int, std::vector<int>, decltype(compare)> q(compare);
您试图将 lambda 表达式 作为参数传递给模板 type 参数。这是行不通的。用 sort
做同样的事情也行不通:
sort<vector<int>::iterator, [](const int &a, const int &b) -> bool {
return a < b;
}>(/*...*/);