- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
Lambda 表达式不允许在未计算的上下文中使用(例如在 decltype 中)并且直到最近才可以是常量表达式。因此无法在模板参数中使用它们。
然而在 C++17 中常量表达式 lambda 是可能的。这仍然不允许在一般的模板参数中使用它们。
然而,特别是对于非类型模板参数,常量表达式 lambda 表达式可以用在计算上下文中,例如:
template<int N> struct S { constexpr static int value = N; };
int main() {
int N = S<[]()constexpr{return 42;}()>::value;
}
但这仍然行不通,因为模板参数中明确不允许使用 lambda 表达式,无论是类型还是非类型。
我的问题是不允许上述构造背后的原因。我可以理解函数签名中的 lambda 类型可能有问题,但这里闭包类型本身无关紧要,只使用(编译时常量)返回值。
我怀疑原因是 lambda 主体中的所有语句都将成为模板参数表达式的一部分,因此如果主体中的任何语句在替换期间格式错误,则需要应用 SFINAE。这可能需要编译器开发人员进行大量工作。
但这实际上是我的动力。如果可以使用上面的构造,那么 SFINAE 不仅可以用于常量表达式,还可以用于 constexpr 函数中有效的其他语句(例如文字类型声明)。
除了对编译器编写者的影响之外,这是否会导致任何问题,例如标准中的歧义、矛盾或复杂性?
最佳答案
lambda 不出现在未计算的上下文中是有意为之的。 lambda 始终具有唯一类型这一事实会导致各种问题。
这里有几个例子来自 comp.lang.c++ discussion ,来自丹尼尔·克鲁格勒:
There would indeed exist a huge number of use-cases for allowing lambda expressions, it would probably extremely extend possible sfinae cases (to include complete code "sand-boxes"). The reason why they became excluded was due to exactly this extreme extension of sfinae cases (you were opening a Pandora box for the compiler) and the fact that it can lead to problems on other examples as yours, e.g.
template<typename T, typename U>
void g(T, U, decltype([](T x, T y) { return x + y; }) func);is useless, because every lambda expression generates a unique type, so something like
g(1, 2, [](int x, int y) { return x + y; });
doesn't actually work, because the type of the lambda used in the parameter is different from the type of the lambda in the call to
g
.Finally it did also cause name-mangling issues. E.g. when you have
template<typename T>
void f(T, A<sizeof([](T x, T y) { return x + y; })> * = 0);in one translation unit but
template<typename T>
void f(T, A<sizeof([](T x, T y) { return x - y; })> * = 0);in another translation unit. Assume now that you instantiate
f<int>
from both translation units. These two functions have different signatures, so they must produce differently-mangled template instantiations. The only way to keep them separate is to mangle the body of the lambdas. That, in turn, means that compiler writers have to come up with name mangling rules for every kind of statement in the language. While technically possible, this was considered as both a specification and an implementation burden.
这是一大堆问题。特别是考虑到您的写作动机:
int N = S<[]()constexpr{return 42;}()>::value;
可以通过以下方式轻松解决:
constexpr auto f = []() constexpr { return 42; }
int N = S<f()>::value;
关于c++ - 在非类型模板参数中计算 constexpr lambda,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39792593/
可以使用 lambda 和函数创建有序对(Lisp 中的缺点),如 Use of lambda for cons/car/cdr definition in SICP 所示。 它也适用于 Python
我正在尝试从另一个调用一个 AWS lambda 并执行 lambda 链接。这样做的理由是 AWS 不提供来自同一个 S3 存储桶的多个触发器。 我创建了一个带有 s3 触发器的 lambda。第一
根据以下源代码,常规 lambda 似乎可以与扩展 lambda 互换。 fun main(args: Array) { val numbers = listOf(1, 2, 3) f
A Tutorial Introduction to the Lambda Calculus 本文介绍乘法函数 The multiplication of two numbers x and y ca
我想弄清楚如何为下面的表达式绘制语法树。首先,这究竟是如何表现的?看样子是以1和2为参数,如果n是 0,它只会返回 m . 另外,有人可以指出解析树的开始,还是一个例子?我一直找不到一个。 最佳答案
在 C++0x 中,我想知道 lambda 函数的类型是什么。具体来说: #include type1 foo(int x){ return [x](int y)->int{return x * y
我在其中一个职位发布中看到了这个问题,它询问什么是 lambda 函数以及它与高阶函数的关系。我已经知道如何使用 lambda 函数,但不太自信地解释它,所以我做了一点谷歌搜索,发现了这个:What
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
Evaluate (((lambda(x y) (lambda (x) (* x y))) 5 6) 10) in Scheme. 我不知道实际上该怎么做! ((lambda (x y) (+ x x
我正在处理 MyCustomType 的实例集合如下: fun runAll(vararg commands: MyCustomType){ commands.forEach { it.myM
Brian 在他对问题 "Are side effects a good thing?" 的论证中的前提很有趣: computers are von-Neumann machines that are
在 Common Lisp 中,如果我希望两个函数共享状态,我将按如下方式执行 let over lambda: (let ((state 1)) (defun inc-state () (in
Evaluate (((lambda(x y) (lambda (x) (* x y))) 5 6) 10) in Scheme. 我不知道实际上该怎么做! ((lambda (x y) (+ x x
作为lambda calculus wiki说: There are several possible ways to define the natural numbers in lambda cal
我有一个数据类,我需要初始化一些 List .我需要获取 JsonArray 的值(我使用的是 Gson)。 我做了这个函数: private fun arrayToList(data: JsonAr
((lambda () )) 的方案中是否有简写 例如,代替 ((lambda () (define x 1) (display x))) 我希望能够做类似的事情 (empty-lam
我在 Java library 中有以下方法: public void setColumnComparator(final int columnIndex, final Comparator colu
我正在研究一个函数来计算国际象棋游戏中棋子的有效移动。 white-pawn-move 函数有效。当我试图将其概括为任一玩家的棋子 (pawn-move) 时,我遇到了非法函数调用。我已经在 repl
考虑这段代码(在 GCC 和 MSVC 上编译): int main() { auto foo = [](auto p){ typedef decltype(p) p_t;
我正在阅读一个在 lambda 内部使用 lambda 的片段,然后我想通过创建一个虚拟函数来测试它,该函数从文件中读取然后返回最大和最小数字。 这是我想出来的 dummy = lambda path
我是一名优秀的程序员,十分优秀!