C++中C99风格的变长数组函数签名

4
在C99中,我们可以这样编写函数签名:
void func(int dim1, int dim2, float A[dim1 * dim2]);
dim1dim2是运行时参数。这很好,因为任何使用此函数的用户都能立即了解A的维度,并且可以在不阅读注释/文档的情况下推断出更多信息。特别是如果dim1dim2是具有超出此处所示语义的参数。

是否可能在C++中编写一个接口,以提示函数期望的向量/张量的维数和大小?维数可能可以编码为模板参数(我特别不喜欢,但那是另一个话题),但大小呢?有什么想法吗?

更新:

我想我需要更清楚一些。C++函数看起来像这样:

void func(int dim1, int dim2, std::vector<float> A);

其中两个维度中的一个甚至可以省略(因为它是A.size()/dim)。但签名并没有告诉用户函数所期望的向量大小。当然,我可以使用assert(A.size() == dim1*dim2);等方法。但这不是我的问题所在,我的问题是如何使接口更加信息化。

更新2:

所以我非常确定我需要的是这个:

typedef int dim1; 
typedef int dim2; 
void func(Matrix<dim1, dim2> A);

正如答案中提到的,信息必须是特定类型的。

3
为什么不使用一种可以告诉你其大小/尺寸的类型?那样就不需要“提示”了。 - Mike Seymour
@MikeSeymour,就像我之前所说的,dim1和dim2是运行时参数。它们在编译时不可知,也无法编码到类型中。 - Sebastian
1
@Sebastian,不需要在类型中编码。例如,std::vector具有运行时大小。您仍然可以检索它并很好地执行它。 - chris
2
@Sebastian:抱歉,我应该更详细地说明。我的意思是“使用具有接口的类型,该接口可用于确定给定实例的大小/尺寸,类似于标准容器的size()成员”,而不一定是静态编码信息的类型。 - Mike Seymour
在C语言中,参数float A[X]float* A是完全相同的。我敢打赌,在C++中也是如此(出于兼容性考虑)。你可以在其他地方记录类型,或者创建一个宏#define PARAM_DIM(x),将其扩展为空:float A[PARAM_DIM(x * y)] -> float A[] - Tim Čas
2个回答

5
在C++中,你会这样写:void func(Matrix const& A)。矩阵的维度将被编码在矩阵本身中,因此不需要单独传递它们。这既确保了维度的准确性,又简化了调用习惯。

我当然同意你的观点,但那不是我想问的吧。一个函数签名 void mix(int apples, int oranges, float mixture[apples * oranges]);void mix(Matrix<float> mixture); 传达更多信息,对吗? - Sebastian
1
@Sebastian,矩阵本质上具有两个已知大小的维度和这些维度相乘的总大小。对于这些维度和乘法的额外参数都是多余的。 - chris
@chris 我知道这些。不过现在我已经想到了我想要的,我想给矩阵的维度命名。 - Sebastian
1
@Sebastian:确实,函数签名本身传达的信息较少。信息将来自参数类型。这通常被认为是一件好事。 - Mike Seymour
你说得对。我非常确定我想要这个:typedef int dim1; typedef int dim2; void func(Matrix<dim1, dim2> A); 我完全同意@MikeSeymour - 谢谢! - Sebastian

0
你可以使用 std::array:
void func(std::array<int, /* dimension */> &arr);

1
dim1dim2是运行时参数,std::array是一个用于常量(在编译时)大小数组的容器。 - Sebastian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接