const指针作为参数传递给constexpr函数

时间:2018-08-11 11:50:22

标签: c++ constexpr constant-expression

我正在做一些非常基本的问题,以熟悉模板元编程。特别是,这只是将方矩阵的右下对角线上的值相加([0,0][1,1]等的索引)。我已经用不同的constexpr函数以多种方式解决了这个问题,但是我不明白为什么一种特殊的方式会失败。下面的代码和错误消息:

constexpr int DRsum(const int* starter, const size_t size, int itr = 0)
{
    if(itr==size-1)
    {
        return *starter;
    }
    size_t sum = 0;
    sum = *starter;
    sum += DRsum(starter+size+1, size, itr+1);
    return sum;
}

int main()
{
    static const size_t size = 3;

    static constexpr const int matrix[][size] = {
    {1,2,3},
    {4,5,6},
    {7,8,9}
    };

    static constexpr int const* baseptr = &matrix[0][0];

    constexpr int sum = DRsum(baseptr, size);
}

错误消息如下:

main.cpp|69|  in constexpr expansion of 'DRsum((& matrix[0][0]), 3u, 0)'|
main.cpp|39|  in constexpr expansion of 'DRsum((starter + ((((sizetype)size) + 1u) * 4u)), 
    ((size_t)size), (itr + 1))'|
main.cpp|69|error: '* starter' is not a constant expression|

我不确定为什么要这样做,因为我是Template Metaprogramming的新手。我做了一个虚拟函数,以测试指针取消引用是否是问题所在,并且效果很好。我的猜测是,这可能与我传递一个指针而不是传递给constexpr指针有关,但我不确定。任何帮助将不胜感激,谢谢。

此外,我已经通过仅传入整个结构(直接向上复制一个深拷贝)解决了这个问题,但是我更想知道如何通过浅拷贝或指针将内容传递给constexpr函数。谢谢。

1 个答案:

答案 0 :(得分:0)

2D数组(矩阵)不能被视为1D数组,因此starter+size+1导致不确定的行为。通常,未定义的行为是未定义的,因此程序可以按预期工作,但是当在需要常量表达式的结构内发生未定义的行为时,程序将变得格式错误,从而编译器会发出错误。

我认为没有简单的解决方法,因为没有明确定义的方法可以通过startereven with std::launder)访问整个2D数组,除非您更改{{1 }}。例如,您可以这样编写DRsum

DRsum

然后将其命名为template <size_t size> constexpr int DRsum(const int (*starter)[size], int itr = 0) { if (itr == size - 1) { return (*starter)[itr]; } size_t sum = 0; sum = (*starter)[itr]; sum += DRsum(starter + 1, itr + 1); return sum; }