【发布时间】:2021-02-16 13:47:29
【问题描述】:
我试图在编译时验证给定的 lambda 是否接受某种类型(在我的示例代码中为双精度)。只要 lambda 的签名明确指定了此工作的类型。但是,一旦我在签名中使用带有 auto 的通用 lambda,在评估 requires 语句时就会出现编译错误。
以下代码 sn -p 说明了问题(also on compiler explorer)
#include <concepts>
#include <iostream>
#include <string>
template<typename F>
concept accepts_double = requires(F f, double d) { f(d); };
struct Component{};
int main(){
auto f1 = [](double a){double b = a;};
auto f2 = [](std::string a){std::string b = a;};
auto f3 = [](auto a){std::string b = a;};
std::cout << std::boolalpha << accepts_double<decltype(f1)> << "\n"; // expected true
std::cout << std::boolalpha << accepts_double<decltype(f2)> << "\n"; // expected false
//This one gives the error:
std::cout << std::boolalpha << accepts_double<decltype(f3)> << "\n"; // expected false, gives compilation error
}
我的印象是 requires 语句将验证 f(d);是一个有效的表达式,如果不是,将返回 false。但是,当使用最新的 gcc 和 clang 进行编译时,我收到一个错误,表明它正在尝试评估函数体:
:13:38: error: no viable conversion from 'double' to 'std::string' (aka 'basic_string<char>')
我的问题是否有不同的方法来确保 lambda 可以传递一个双精度值,或者要求语句仅限于检查签名?
【问题讨论】:
-
我认为这可能是一个错误。当我们使用带有
operator()模板的手工仿函数时,这个概念就通过了。成员的定义没有被实例化。
标签: c++ c++20 compile-time