提问人:Mikhail 提问时间:2/25/2023 最后编辑:DailyLearnerMikhail 更新时间:2/25/2023 访问量:71
C++ 选择性预定义函子初始化 [复制]
C++ selective predefined functor initializaiton [duplicate]
问:
预定义的函子需要就地实例化(带空括号)才能在算法中使用,但不能用作容器适配器(如 priority_queue)的类型参数。为什么会有这种差异?
#include <queue>
#include <vector>
#include <numeric>
int main(){
std::priority_queue<int, std::vector<int>,
// parentheses are NOT needed here: std::greater<>
std::greater<>> pq;
pq.push(1);
pq.push(2);
pq.push(3);
std::vector<int> v = {1, 2, 3};
auto result = accumulate(v.begin(), v.end(), 0,
// parentheses are needed here std::plus<>()
std::plus<>());
}
答:
4赞
Vlad from Moscow
2/25/2023
#1
std::priority_queue
是具有类型模板参数的类模板。其专用化需要指定类型模板参数。并且是用作类型模板参数的类型。std::greater<>
另一方面,在算法中,您需要提供一个函数对象,例如 。std::greater<>()
1赞
463035818_is_not_an_ai
2/25/2023
#2
在这两种情况下,可调用对象的类型都是模板参数。对于 you 显式声明模板参数,类型。通过传递比较器的实例,使模板 arugment(可以推断出比较器的类型)。std::priority_queue
std::accumulate
使用 CTAD(类模板参数演绎),这种差异就不那么明显了。如果你愿意,你可以反过来说:
#include <numeric>
#include <queue>
int main() {
std::priority_queue pq(std::greater<int>{},std::vector<int>{});
std::vector<int> x;
std::accumulate<std::vector<int>::iterator,int,std::greater<>>(x.begin(),x.end(),0,{});
}
在这里,我利用 CTAD 让构造函数推断传递给构造函数的参数的类型。然后,它相当不常见,但如果您愿意,您可以显式指定算法的临时参数。尽管您仍然需要传递默认构造的实例,因为二进制操作的默认值没有重载(可能有,它只是没有那么有用,因为通常您只想编写并推导出所有模板参数)。std::accumulate
std::accumulate(..)
评论
0赞
Mikhail
2/25/2023
哦,这个例子是有道理的。虽然头很痛
评论
std::max(7, int)