我本来希望包含一个最小的例子,但由于我的问题的性质,我不能提供一个。
我将我的问题减少到无法对数组进行类型转换。这是一个代码片段,显示了我想写的内容:
template <size_t N>
size_t arrLen(int(&data)[N])
{
return N;
}
int main(int argc, char** argv)
{
int arr[] = { 1, 2, 3, 4, 5, 6 };
size_t working = arrLen(arr);
int * p = &arr[1];
size_t len = 3;
size_t len_is_not_a_constant_value = arrLen(*(int(*)[len])p);
}
我的游乐场算法是在一维阵列中找到任何峰值,其中峰值被定义为大于或等于峰值邻居。算法本身对我来说并不重要。下面的代码已经注释掉了我想要包含但不能编译的行,因为它不会编译。没有那些行,算法是不正确的。
template <size_t N>
int getpeak1D_templated(int(&data)[N])
{
size_t offset = N / 2;
if (data[offset] < data[offset - 1])
{
int * p = data;
size_t len = offset;
//return getpeak1D_templated(*(int(*)[len])p);
return 0;
}
else if (data[offset] < data[offset + 1])
{
int * p = &data[offset];
size_t len = N - offset;
//return offset + getpeak1D_templated(*(int(*)[len])p);
return 0;
}
else
{
return offset;
}
}
int getpeak1D_templated(int(&data)[1])
{
return 0;
}
int getpeak1D_templated(int(&data)[2])
{
if(data[0] < data[1]) return 1;
return 0;
}
这是未模板化的版本。这将编译并且应该是正确的。
int getpeak1D(int * data, size_t N)
{
size_t offset = N / 2;
size_t offset_m1 = offset - 1;
size_t offset_p1 = offset + 1;
if (N >= offset_m1 && data[offset] < data[offset_m1])
{
return getpeak1D(data, offset);
}
else if (N >= offset_p1 && data[offset] < data[offset_p1])
{
return offset + getpeak1D(data + offset, N - offset);
}
else
{
return offset;
}
}
我可以看到为什么*(int(*)[len])p
无效。
感觉有些东西我不知道了。这个递归终止,我将能够手动编写所有特化(对于合理的起始数组大小)。我假设我在这里做错了。不知何故,这种递归应该可以使用模板。
是否有我丢失的数组转换版本?
我错过了一些完全不同的东西吗?
编辑: 我实际上可以看看为什么这是无效的。我的观点是N是常量,并且所有操作都定义得很好,以至于它们可以在编译时解析。因此,对于大小为N的数组,递归的所有分支都可以展开。我正在寻找一种到达那里的方法。演员表是不正确的,永远不会是正确的。
答案 0 :(得分:1)
错误应该很清楚。例如,len
不是编译时常量,并且您不能拥有可变长度数组(或者转换为指向它的指针)。其次,arrLen
如何在编译时实例化,而不知道len
是什么?
使用非模板版本。
答案 1 :(得分:1)
如果start.sh
不是编译时常量积分表达式,则无法实现此目的。它也没什么意义.¹
你真的需要通过len
或类似的。请参阅CppCoreGuidelines:https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Ri-array
您可以随时启用array_view
并进行强制转换:
len
答案 2 :(得分:1)
你不能只用N / 2和N-N / 2替换注释行中的len。 像这样:
template <size_t N>
int getpeak1D_templated(int(&data)[N])
{
size_t ret = 0;
size_t offset = N / 2;
if (data[offset] < data[offset - 1])
{
int * p = data;
ret = getpeak1D_templated(*(int(*)[N/2])p);
}
else if (data[offset] < data[offset + 1])
{
int * p = &data[offset];
ret = offset + getpeak1D_templated(*(int(*)[N - N/2])p);
}
else
{
ret = offset;
}
return ret;
}
int getpeak1D_templated(int(&data)[1])
{
return 0;
}
int getpeak1D_templated(int(&data)[2])
{
if(data[0] < data[1]) return 1;
return 0;
}