const 指针作为参数传递给 constexpr 函数
const pointers passed as argument into constexpr function
我正在做一些非常基本的问题来熟悉模板元编程。特别是这个只是将方阵右下对角线上的值相加([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|
我不确定为什么会这样,因为我是模板元编程的新手。我做了一个虚拟函数来测试指针取消引用是否是问题所在,结果很好。我的猜测是,这可能与我传递一个指针而不是指向 constexpr 指针的指针有关,但我不确定。任何帮助将不胜感激,谢谢。
此外,我已经通过传递整个结构(直接向上复制)解决了这个问题,但我更想知道如何通过浅复制或指针将内容传递到 constexpr 函数中。谢谢。
二维数组(矩阵)不能被视为一维数组,因此 starter+size+1
导致未定义的行为。通常未定义的行为是未定义的,因此程序可能会按预期运行,但是当在需要常量表达式的结构中发生未定义的行为时,程序会变得不正确,因此编译器会发出错误。
我认为没有简单的修复方法,因为没有明确定义的方法通过 starter
() 访问整个二维数组,除非您更改 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;
}
然后像 constexpr int sum = DRsum(matrix);
那样称呼它。
我正在做一些非常基本的问题来熟悉模板元编程。特别是这个只是将方阵右下对角线上的值相加([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|
我不确定为什么会这样,因为我是模板元编程的新手。我做了一个虚拟函数来测试指针取消引用是否是问题所在,结果很好。我的猜测是,这可能与我传递一个指针而不是指向 constexpr 指针的指针有关,但我不确定。任何帮助将不胜感激,谢谢。
此外,我已经通过传递整个结构(直接向上复制)解决了这个问题,但我更想知道如何通过浅复制或指针将内容传递到 constexpr 函数中。谢谢。
二维数组(矩阵)不能被视为一维数组,因此 starter+size+1
导致未定义的行为。通常未定义的行为是未定义的,因此程序可能会按预期运行,但是当在需要常量表达式的结构中发生未定义的行为时,程序会变得不正确,因此编译器会发出错误。
我认为没有简单的修复方法,因为没有明确定义的方法通过 starter
(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;
}
然后像 constexpr int sum = DRsum(matrix);
那样称呼它。