在回答this question时,我使用gcc(code compiled)和clang(code rejected)尝试了以下代码:
typedef long (*func)(int);
long function(int) { return 42; }
struct Test
{
static constexpr func f = &function;
};
template<func c>
struct Call
{
static void f()
{
c(0);
}
};
int main()
{
Call<Test::f>::f();
}
我不确定哪个编译器是正确的,虽然我认为 Test::f
的constexpr初始化是可以的 . 错误clang输出是:
error: non-type template argument for template parameter of pointer type 'func'
(aka 'long (*)(int)') must have its address taken
-
哪个编译器是对的?
-
如果铿锵是对的,为什么,这个错误究竟意味着什么?
EDIT :对于"why",请参阅DyP's question .
1 回答
(n3485,强调我的)
我不知道为什么它受到限制,但我认为它可能与函数地址在编译时不可用的事实有关(可能有替代模板实例化的目的) .
编辑:由于Synxis的后续问题(评论)而增强了答案
^这是良好的形式;您可以使用函数的地址来初始化
constexpr
对象 . 问题是它明确被禁止使用指针作为非类型模板参数而不是&identifier
形式: