C++ GCC 10.2不接受lambda空lambda作为constexpr std::function<;void()>;
我在玩constexpr时发现GCC拒绝了这个看似有效的代码:C++ GCC 10.2不接受lambda空lambda作为constexpr std::function<;void()>;,c++,gcc,C++,Gcc,我在玩constexpr时发现GCC拒绝了这个看似有效的代码: #include <functional> constexpr void test(const std::function<void()>& a) { a(); } int main() { test([](){}); } #包括 constexpr无效测试(const std::function&a){ a(); } int main(){ 测试([](){}); }
#include <functional>
constexpr void test(const std::function<void()>& a) {
a();
}
int main() {
test([](){});
}
#包括
constexpr无效测试(const std::function&a){
a();
}
int main(){
测试([](){});
}
我去了godbolt,而clang恰好很好地编译了这段代码。这是GCC中的错误吗?下面是注释中已经提到的,
std::function
本身不能用于constexpr
环境,因为操作符()()
以及std::function
的构造函数不是constexpr
因此,您可以直接使用指向函数的指针,如果捕获的lambda较少,或者您可以在C++20中像这样对函数进行模板化:
constexpr void test(auto&& a) {
a();
}
<>或在显式模板参数中使用旧的C++标准。
根据需要使用auto
或auto&
或auto&
来允许临时lambda,将其移入或复制(优化后可能相同)
摘自评论:
constexpr函数必须至少有一组可以在常量表达式中计算的输入,否则它的格式不正确,不需要诊断*
因为clang没有报告某些内容,并不意味着它是一个clang bug。对我来说,gcc看起来还可以,因为调用a()可能会产生副作用,这违反了test()成为constexpr的要求。@Klaus我不太确定。lambda的定义是可见的,它显然是constexpr,所以我认为clang就在这里。另外,错误是关于调用
a()
,而不是test
的constexpr ness。使函数constexpr void test(void(*a)()
甚至使gcc感到高兴,所以我猜它与std::function
有关。它缺少constexpr
构造函数,这可能是一回事。@cigien即使lambda的调用是constexpr,std::function constexpr的操作符()是吗?我不相信@这是否意味着我不能使用std::function is constexpr context?参数auto&不允许lambda。它必须是(auto a)@Hemil:你几乎是对的:-)它不允许临时:-)所以auto&&或auto是可以的,但是auto func=[](){};测试(func);这与auto&配合得很好。我会修好的!值得一提的是,如果您认为是这样的话,这是一个叮当作响的错误。@cigien means?如果您想要与std::function
相同的约束,那么参数可以是std::invocable auto a