C++20 concept / requires expression to test if generic lambda accepts type(C++20概念/需要表达式来测试泛型lambda是否接受类型)
问题描述
我试图在编译时验证给定的lambda是否接受某种类型(在我的示例代码中为Double)。只要lambda的签名明确指定了类型,它就可以工作。但是,只要我在签名中使用带有AUTO的泛型lambda,在计算Requires语句时就会出现编译错误。
以下代码片段说明了该问题(also on compiler explorer)
我的印象是,Requires语句将验证f(D);是否为有效表达式,否则将返回FALSE。但是,当使用最新的GCC和clang进行编译时,我得到一个错误,指示它正在尝试计算函数体:
我的问题有没有其他方法可以确保向lambda传递双精度值,或者是否将Requires语句限制为仅检查签名?
推荐答案
这是预期行为。
lambdaf3
声称接受任何。但是要测试它是否可以通过double
调用,我们需要实例化调用操作符。只有该实例化的直接上下文中的失败才算作替换失败--其中直接上下文基本上是与实际函数签名密切相关的任何东西。一旦我们进入调用操作符的主体,这就不再是直接的上下文了。我们必须实例化Body,这会失败(无法从double
构造string
),但这是一个严重的编译器错误。
换句话说,这对SFINAE不友好。
现在,需要实例化lambda主体的唯一原因是它返回
auto
,而我们需要知道返回类型。我们可以直接提供:
此处,accepts_double<decltype(f3)>
编译。但它给了true
!因为Lambda确实声称接受一切。这里根本没有任何限制。由于我们碰巧不必实例化正文,因此我们避免了编译失败。
如果我们希望确保编译并提供正确的答案,则需要添加该约束:
现在,我们实际上将参数限制为允许的类型集。这将编译并正确生成false
(当然,因为double
不能转换为std::string
)。
这篇关于C++20概念/需要表达式来测试泛型lambda是否接受类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!