C++ GCC 10.2不接受lambda空lambda作为constexpr std::function<;void()>;

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(){ 测试([](){}); }

我在玩constexpr时发现GCC拒绝了这个看似有效的代码:

#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