【发布时间】:2017-05-02 10:30:20
【问题描述】:
考虑一个例子:
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: 错误:'main()::::_FUN' 不是类型'void (*)()' 的有效模板参数,因为'static constexpr void main()::: :_FUN()' 没有链接
prog.cc:7:8: 注意:非 constexpr 函数 'operator void (*)()' 不能在常量表达式中使用
【问题讨论】:
-
lambda没有链接,因为eel.is/c++draft/basic.link#8 当然operator()不是constexpr,所以这是首先发出什么错误的问题 - 我错了吗?跨度> -
@skypjack 经过一番搜索后,我得出了相同的结论(这与
A没有链接的原因相同)。而且,除此之外,没有链接的类型不能用作模板参数。
标签: c++ lambda language-lawyer constexpr