调用constexpr函数接受数组无法编译

时间:2017-02-09 17:30:10

标签: arrays c++14 constexpr non-type template-variables

考虑以下代码:

#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

这是根据标准还是错误?是什么让第二行在第一行通过时失败?

2 个答案:

答案 0 :(得分:2)

所有constexpr函数必须同时包含constexpr和非constexpr参数。或者,简而言之,constexpr函数的参数在正文中不是constexpr,但如果它们在函数体外是constexpr,则根据它们的certian计算可能是{{1从函数返回时。

constexpr

如果theIntArray<xx[0]>; xx[0],这只是有效的语法,但在函数体constexpr不是 xx

constexpr

live example

答案 1 :(得分:1)

区别在于constexpr函数参数不存在。也就是说,你做不到

constexpr auto fun(int x) {
    constexpr y = x;
    return y;
}

并且你也不能在函数内部使用函数参数xx[0]作为非类型模板参数。它与aa[0]不同,因为它是在函数外部进行评估的。

执行所需操作的唯一方法是使函数参数成为非类型模板参数。为此,请参阅@Yakk的答案,其中他使用对constexpr数组的const-reference作为非类型模板参数。