问题Lambda expressions as class template parameters询问使用lambda表达式作为类模板参数的可能性。
问题的答案是否定的。但是,它是关于C ++ 11的。
新标准C ++ 14中的情况是否发生了变化?
答案 0 :(得分:2)
没有C ++ 14中的情况根本没有改变,实际上5.1.2
Lambda表达式段 2 中的语言已经收紧:
lambda表达式不应出现在未评估的操作数中(Clause 5)。
为:
[...] lambda表达式不应出现在未评估的操作数中 (第5条),在模板参数中,在别名声明中,在 typedef声明,或在函数或函数的声明中 模板在其函数体和默认参数之外。 [注意: 意图是防止lambda出现在签名中。 -结束 注意] [...]
Defect report 1607. Lambdas in template parameters导致这种变化。
缺陷报告只是倾向于处理不允许这样做的理由,但我们可以找到一个非常详细的解释,说明为什么在Rationale for lambda-expressions not being allowed in unevaluated contexts中不允许这样做。原因归结为:
SFINAE
鉴于此限制的理由,似乎不太可能改变。
答案 1 :(得分:1)
新标准C ++ 14中的情况是否发生了变化?
Lambda表达式仍然不会出现在未评估的操作数中 - 与Xeo's Post中的表达式相同的引用也存在于最新公开的N3797草案中,位于完全相同的位置。
但是,每个闭包类型都有一个删除的默认构造函数(N3797,§5.1.2/ 20):
与 lambda-expression 关联的闭包类型已删除 (8.4.3)默认构造函数和删除的复制赋值运算符。
因此,对于portabiliby和标准一致性(可能是代码在合理的编译器上工作),您需要将一个闭包对象传递给要复制的实例化类的构造函数。但要传递与该专业化的模板参数相同类型的闭包 ,您必须首先定义它:
using my_map_type = map<int, int, decltype([] (auto&& lhs, auto&& rhs) {return lhs < rhs*4;})>;
// Assuming the above compiles
my_map_type m( [] (auto&& lhs, auto&& rhs) {return lhs < rhs*4;} );
// Different closure type - compiler error! What do you copy from!?
没有任何合法的方法来创建第一个lambda的闭包类型的单个对象。因此,即使要删除所述规则,也无法创建my_map_type
的单个实例。其他“闭包类型作为模板参数”方案也会出现类似问题。