【发布时间】:2019-05-04 09:00:08
【问题描述】:
我目前正在处理一些需要使用 lambda 作为模板参数的代码,如下例所示:
#include <iostream>
template<void(*func)(int)>
struct FunctionCaller{
FunctionCaller() {func(5);}
};
void RealFunction(int i){
std::cout << i*2 << std::endl;
}
int main(){
FunctionCaller<[](int i){std::cout << i << std::endl;}> caller; //should print 5
FunctionCaller<RealFunction> caller2; //should print 10
return 0;
}
我尝试使用 GCC 和 Clang 的最新(支持 C++17)版本(分别为 8.2.1 和 7.0.0 版本)编译此示例,以获取各种错误,这些错误相当于模板参数中不允许使用 lambda 表达式。我正在使用正确的编译器标志来启用 C++17 支持。
然而,这在我看来应该可以工作,因为《C++ Primer 5th edition》一书说任何常量表达式都可以用于非类型模板参数,并且在 C++17 中,这个 Stack Overflow 帖子告诉我lambda 是 C++17 及更高版本中的常量表达式。
经过广泛研究,似乎 C++17 标准明确禁止将 lambdas 作为模板参数。这种限制背后的理由是什么?如果不到位会爆炸什么?
编辑:This 问题有一些相关信息,但它只是说存在此限制是为了防止 lambda 出现在方法签名中,而没有任何信息说明为什么会出现问题。
【问题讨论】:
-
这个问题不是链接问题的重复,因为该问题与 STL 模板的使用有关,而这个问题是关于创建新的类模板。此外,链接问题的已接受答案说模板不能在类似 decltype 的上下文中使用(未评估),但可以肯定的是,实例化调用 lambda 的模板会评估该 lambda。
-
你也可以看看stackoverflow.com/questions/1174169/… 可以解决你的问题
-
@VasanthAlagiriswamy 我知道一些解决方法,但我不知道为什么我的原始解决方案不起作用这一事实表明我的 C++ 知识存在一个漏洞,我想纠正。跨度>
-
@PasserBy 唯一相关的信息是这确实是故意的,并且由于某种原因,方法签名中的 lambdas 是一个问题。目前尚不清楚为什么这是个问题。
标签: c++ templates lambda language-lawyer c++17