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

标签 c++ lambda language-lawyer 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,一元 + 返回的函数没有链接,相反,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/

相关文章:

C++ 重载宏

c# - .NET 4.0 中的表达式树 : Expression. 调用无法在类型 List<T> 中找到方法 "get_Item"

c++ - 列表初始化的重载解析规则是什么

css - 影子 DOM 是否替换了::before 和::after?

c++ - 包含 netinet/in.h 和 netinet6/in6.h 时重新定义类型

c++ - 有unique_from_this()吗?或者如何从继承自 enable_shared_from_this 的类返回 unique_ptr

c++ - 类似命名空间的宏功能

C++14 Lambda - 通过引用或值有条件地捕获

python按值排序json列表

css - 在 CSS 视觉格式模型中, "the flow of an element"是什么意思?