【发布时间】:2018-08-11 11:50:22
【问题描述】:
我正在做一些非常基本的问题来熟悉模板元编程。特别是这个只是将方阵右下对角线上的值相加([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 函数。谢谢。
【问题讨论】:
-
指针不是常量,它指向的东西在你的声明中是常量,所以有一个误解。其次,你说的是模板元编程,但是这里没有涉及到模板!?
-
即使在函数参数列表和指针声明中的 * 之后添加了 const,它仍然给我错误消息 "main.cpp|68|error: '(const int )starter' 不是常量表达式|"。基本上我将 baseptr 从 static constexpr int const* 重新定义为 static constexpr int const* const (我认为 constexpr 无论如何都暗示了一个指针)。
-
@SaswatMishra 您使用的是哪个编译器? gcc 很好,只是您正在访问超出其边界的数组godbolt.org/g/4M2sG3
-
@vdavid 我正在使用 GCC 5.1.0,我很确定“越界”错误消息是编译器对我正在犯的其他一些错误的误解,因为当我更改变量时底部的声明从“constexpr int sum”到“int sum”(使 DRsum 在运行时运行),一切正常,我得到正确的值。函数逻辑(就索引访问而言)很好,我的编译器只是抛出了一个关于 starter 不是常量表达式的问题。
-
问题中没有模板,所以我删除了与模板相关的标签。如果您不同意,请随时回滚。
标签: c++ constexpr constant-expression