首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么C++17标准没有引入部分类模板参数推导?

为什么C++17标准没有引入部分类模板参数推导?
EN

Stack Overflow用户
提问于 2018-05-28 19:31:30
回答 4查看 715关注 0票数 13

我希望我能够使用新的模板参数推导的地方之一,是在构造std::set的/ std::maps /任何其他带有自定义比较器的容器-我的目标是创建一条一行语句,这将创建一个高效的带有lambda比较器的集合。

代码语言:javascript
复制
std::set<int, std::function<bool(int, int)>> s([](int a, int b) {return a > b;});

但由于它使用的是std::function,所以它的速度要慢得多。

另一种选择是:

代码语言:javascript
复制
auto mycomp = [](int a, int b) {return a > b; };
std::set<int, decltype(mycomp)> s(mycomp);

它完成了工作,但1)它需要2行代码,并创建mycomp变量2)我需要显式地传递mycomp的类型。

正如我在参考页上读到的,没有一个标准容器有针对这种情况的推导指南。不幸的是,恐怕使用当前的语言标准(C++17)也不能做到这一点,因为我们可以发现:

仅当不存在模板参数列表时,才会执行

类模板参数推导。如果指定了模板参数列表,则不会进行演绎。

这背后的原因是什么?为什么他们不允许部分参数演绎?我猜它有一些我忽略的问题,但在我看来,它将不仅仅是有帮助的。

EN

回答 4

Stack Overflow用户

发布于 2018-05-28 19:40:44

作为替代方案,您仍然可以将旧的make_xxx

代码语言:javascript
复制
template <typename T, typename COMP>
std::set<T, COMP> make_set(COMP comp)
{
    return std::set<T, COMP>{comp};
}


auto s = make_set<int>([](int a, int b) {return a > b; });
票数 11
EN

Stack Overflow用户

发布于 2018-05-28 19:43:00

在一行中(C++17)

代码语言:javascript
复制
std::set s(std::initializer_list<int>{}, [](int a, int b) {return a > b; });
票数 11
EN

Stack Overflow用户

发布于 2018-05-28 19:35:40

您应该做的是编写一个比较器函数器类型,因此在使用set时不需要代理它。这将是更多的代码行(残暴!),但实际上在每一个方面都更好:

代码语言:javascript
复制
struct MyComparator
{
    bool operator()(int a, int b) const { ...; }
};
using MySet = std::set<int, MyComparator>;

从那时起,您只需在需要的地方创建自定义排序集。

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50565431

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档