提问者:小点点

为什么 lambda 在转换为函数指针时不能在 constexpr 上下文中使用?


考虑一个例子:

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,unary 返回的函数没有链接,clang 相反,函数的强制转换运算符没有声明为 constexpr。有什么理由不允许在 constexpr 上下文中使用 lambda 强制转换为函数指针吗?

查找以下由编译器和现场演示生成的错误:

海湾合作委员会:

prog.cc:7:14:错误:“main()::::_FUN”不是类型“void (*)()”的有效模板参数,因为“static constexpr void main()::::_FUN()”没有链接

铛:

prog.cc:7:8:注意:非constexpr函数“运算符void(*)()”不能在常量表达式中使用


共1个答案

匿名用户

Clang还没有实现constexpr lambdas。

海湾合作委员会在其他方面落后。[temp.arg.nontype]/2 唯一有趣的约束是参数应该是一个常量表达式。但是 [expr.const]/(5.2) 使它成为一个,所以这是完全有效的。也许GCC还没有实施N4198,这消除了链接要求。

请注意,constexpr lambda 和无链接函数指针模板参数都是 C 14 后的功能。