调用接受数组的 constexpr 函数无法编译
Call to constexpr function accepting an array fails to compile
考虑这段代码:
#include <array>
template < int... Ints >
constexpr std::array<int,sizeof...(Ints)> theIntArray = {Ints...};
template < size_t NN >
constexpr void test(const std::array<int,NN>& xx)
{
theIntArray<xx[0]>;
}
constexpr std::array<int,2> aa = {10,20};
int main()
{
theIntArray<aa[0]>; // passes
test(aa); // FAILS ?!
return 0;
}
在 main()
函数中,第一行通过而第二行失败并出现奇怪的错误消息:
error: ‘* & xx’ is not a constant expression
note: in template argument for type ‘int’
我正在使用 gcc-7.0.1,您可以找到实例 here。
这是符合标准还是错误?是什么导致第二行失败而第一行通过?
区别在于constexpr函数参数不存在。也就是说,你不能做
constexpr auto fun(int x) {
constexpr y = x;
return y;
}
也不能在函数内部使用函数参数 xx[0]
作为 non-type template-parameter。 aa[0]
不同,因为它是在函数外求值的。
做你想做的唯一方法是使函数参数成为 non-type 模板参数。为此,请参阅@Yakk 的答案,他在其中使用 const-reference 到 constexpr
数组作为 non-type 模板参数。
所有 constexpr
函数必须对 constexpr
和非 constexpr
参数都有效。或者,简而言之,constexpr
函数的参数不在主体内 constexpr
,但如果它们在函数主体外 constexpr
,则依赖于它们的 certian 计算可能是 constexpr
在 return 上来自函数。
theIntArray<xx[0]>;
只有当 xx[0]
是 constexpr
时,这才是有效的语法,但在函数体中 xx
是 not constexpr
.
template < size_t NN, std::array<int,NN> const& xx >
constexpr void test()
{
theIntArray<xx[0]>;
}
考虑这段代码:
#include <array>
template < int... Ints >
constexpr std::array<int,sizeof...(Ints)> theIntArray = {Ints...};
template < size_t NN >
constexpr void test(const std::array<int,NN>& xx)
{
theIntArray<xx[0]>;
}
constexpr std::array<int,2> aa = {10,20};
int main()
{
theIntArray<aa[0]>; // passes
test(aa); // FAILS ?!
return 0;
}
在 main()
函数中,第一行通过而第二行失败并出现奇怪的错误消息:
error: ‘* & xx’ is not a constant expression
note: in template argument for type ‘int’
我正在使用 gcc-7.0.1,您可以找到实例 here。
这是符合标准还是错误?是什么导致第二行失败而第一行通过?
区别在于constexpr函数参数不存在。也就是说,你不能做
constexpr auto fun(int x) {
constexpr y = x;
return y;
}
也不能在函数内部使用函数参数 xx[0]
作为 non-type template-parameter。 aa[0]
不同,因为它是在函数外求值的。
做你想做的唯一方法是使函数参数成为 non-type 模板参数。为此,请参阅@Yakk 的答案,他在其中使用 const-reference 到 constexpr
数组作为 non-type 模板参数。
所有 constexpr
函数必须对 constexpr
和非 constexpr
参数都有效。或者,简而言之,constexpr
函数的参数不在主体内 constexpr
,但如果它们在函数主体外 constexpr
,则依赖于它们的 certian 计算可能是 constexpr
在 return 上来自函数。
theIntArray<xx[0]>;
只有当 xx[0]
是 constexpr
时,这才是有效的语法,但在函数体中 xx
是 not constexpr
.
template < size_t NN, std::array<int,NN> const& xx >
constexpr void test()
{
theIntArray<xx[0]>;
}