考虑一个例子:
template <void (*Foo)()>
struct S {
};
int main() {
struct A {
static void x() { }
};
S<&A::x> s;
}
代码在 clang 中编译,gcc 认为 x
没有链接...
对于使用 lambda 表达式时非常相似的示例:
template <void (*Foo)()>
struct S {
};
int main() {
auto lambda = []{};
S<+lambda> s;
}
gcc 和 clang 都同意不编译代码:根据 gcc,一元 + 返回的函数没有链接,相反,clang 声明该函数的强制转换运算符未声明为 constexpr。是否有任何理由禁止在 constexpr 上下文中使用 lambda 转换为函数指针?
查找编译器和现场演示产生的以下错误:
gcc :
prog.cc:7:14: error: 'main()::::_FUN' is not a valid template argument for type 'void (*)()' because 'static constexpr void main()::::_FUN()' has no linkage
clang :
prog.cc:7:8: note: non-constexpr function 'operator void (*)()' cannot be used in a constant expression
最佳答案
clang hasn't implemented constexpr
lambdas yet .
GCC 在其他方面落后。 [temp.arg.nontype]/2唯一有趣的约束是参数应该是一个常量表达式。但是[expr.const]/(5.2)使它成为一个,所以这是完全有效的。也许 GCC 没有实现 N4198然而,这消除了链接要求。
请注意,constexpr
lambda 和无链接函数指针模板参数都是 C++14 后的特性。
关于c++ - 为什么 lambda 在转换为函数指针时不能在 constexpr 上下文中使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41187571/