我希望我可以使用新模板参数演绎的其中一个地方是构建std::set
' s / std::map
s /任何其他带有自定义比较器的容器 - 我的目标是创建一个单行语句,它将创建一个带有lambda比较器的高效集。
自C ++ 11以来我能做的是:
std::set<int, std::function<bool(int, int)>> s([](int a, int b) {return a > b;});
但由于它使用std::function
,因此速度明显变慢。
另一种选择是:
auto mycomp = [](int a, int b) {return a > b; };
std::set<int, decltype(mycomp)> s(mycomp);
它完成了工作,但1)它需要2行,并创建mycomp
变量2)我需要明确传递mycomp
的类型。
正如我在参考页面上看到的那样,没有一个标准容器有这种情况的扣除指南。不幸的是,我担心它甚至无法用当前的语言标准(C ++ 17)完成,正如人们所能找到的那样:
仅在不存在模板参数列表时才执行类模板参数推导。如果指定了模板参数列表,则不会进行演绎。
这背后的原因是什么?为什么他们不允许部分论证扣除?我想它有一些问题我忽略了,但在我看来,它会有所帮助。
答案 0 :(得分:11)
在一行(C ++ 17)
std::set s(std::initializer_list<int>{}, [](int a, int b) {return a > b; });
答案 1 :(得分:10)
作为替代方案,您仍然可以制作旧make_xxx
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; });
答案 2 :(得分:5)
您应该做的是编写比较器仿函数类型,因此在使用集合时不需要代理它。这将是更多的代码行(暴行!),但几乎在所有方面都更好:
struct MyComparator
{
bool operator()(int a, int b) const { ...; }
};
using MySet = std::set<int, MyComparator>;
从那时起,您只需在需要的地方创建自定义排序的设置。
答案 3 :(得分:0)
由于存在歧义,当存在具有默认值的模板参数时,它会带来歧义。此外,如果是可变参数模板。