如何将数组维度作为模板函数的参数传递 [英] How to pass array dimensions as parameters of a template function
问题描述
我需要一个函数来处理可变大小的二维char数组.以下是我的尝试之一:
I need a function to process a two-dimensional char array of variable sizes. Below is one of my attempts:
int GetCodes( char **codes, size_t N );
template<size_t N>
inline int GetCodes( char (*codes)[N] ){ return GetCodes( codes, N ); };
编译器(VC ++ 2008)抱怨说,它无法将参数1从" char(*)[8]"转换为"char **".所以我将代码更改为:
The compiler (VC++ 2008) complains that it "cannot convert parameter 1 from ''char (*)[8]'' to ''char **''." So I changed the code to:
int GetCodes( char **codes, size_t N );
template<size_t N>
inline int GetCodes( char (*codes)[N] ){ return GetCodes( (char**)codes, N ); };
那将编译并链接.但是,当它运行时,我将得到一个严重的指针错误,并且程序将崩溃.我该如何解决该问题?有没有不用模板就可以实现这一目标的方法?
--------------------------------------
非常感谢所有建议,但我想补充一些说明.首先,我的问题是多维数组(在这种情况下为两个).我已经使用了Phillipe建议的一维数组参考,没有任何问题.我只是不能将其扩展到二维.我确实尝试使用引用,例如,
That would compile and link. However when it is run I would get a bad pointer error and the program would crash. How can I fix the problem? Is there a way to achieve this without using templates?
--------------------------------------
Thanks so much for all the suggestions, but I would like to add a few clarifications. First of all my problem is with multi-dimensional (two in this case) arrays. I have used references for one-dimensional arrays as Phillipe suggested without any problem. I just cannot extend that to two-dimensions. I did try using references such as,
template<size_t N1, size_t N2>>
inline int GetCodes( char (&codes)[N1][N2] ){...};
但这有同样的问题.此外,我不需要第一个维度.以下是更完整的代码以显示预期的用途.
But it has the same problem. Besides, I don''t need the first dimension. Below is a more complete code to show the intended use.
int GetCodes( char **codes, const size_t N );
template<size_t N>
inline int GetCodes( char (*codes)[N] ){ return GetCodes( codes, N ); };
int GetCodes( char **codes, const size_t N )
{
**codes = 'A';
return 1;
}
int main()
{
char codes[100][8];
GetCodes( codes );
return 0;
}
请注意,编译器将函数调用解析为模板函数没有问题.当模板函数尝试调用函数的两参数形式时,发生无法将char(*)[8]转换为char **"错误. Phillipe建议使用"char *(* codes)[N]"作为模板函数的参数.
正如Phillipie所说,在这种情况下,我想使用模板函数.如果那不可能,我将按照Barneyman的建议使用向量.
Please note that the compiler does not have problem resolving the function call to the template function. The "cannot convert char (*)[8] to char **" error occurs when the template function tries to call the two-parameter form of the function. Phillipe''s suggestion of using "char *(*codes)[N]" as the argument of the template function would not work.
As Phillipie said, I''d like to use template functions in this case. If that''s not possible I will use vectors as Barneyman suggested.
推荐答案
假设您要使用如下所示的数据调用函数:
Assuming that you want to call the function with data that look like that:
char* aa[] = { "AA", "BB", "CC", "DD" };
GetCodes(aa);
并且您希望N由编译器自动确定,那么您需要在声明中具有引用并修复括号.
And you want N to be automatically determined by the compiler, then you need to have a reference in the declaration and fix the parenthesis.
template<size_t N>
inline int GetCodes( char *(&codes)[N] ){ return GetCodes( codes, N ); };
需要该引用,以避免自动发生从数组到指针的转换.
例如:
The reference is required to avoid the automatic convertion from array to pointers that would otherwise occurs.
As an example:
template <typename T>
void Test1(T t)
{
std::cout << "Test 1: " << typeid(t).name() << std::endl;
}
template <typename T>
void Test2(T &t)
{
std::cout << "Test 2: " << typeid(t).name() << std::endl;
}
int main()
{
int data[] = { 1, 2, 3, 4 };
Test1(data);
Test2(data);
return 0;
}
这将提供以下输入:
This will give the following input:
Test 1: int *
Test 2: int [4]
我更倾向于只使用STL容器-向量或类似的容器
I''d be more inclined to just use an STL container - vector or similar
为了补充最初的解决方案,并作为对其他解决方案和评论的回应,我提供了一个将二维数组重新解释为一维数组的解决方案.
此代码主要用于教育目的.对于现实生活中的程序,通常建议使用STL或boost.
在该解决方案中,我添加了将所有项设置为模的全局代码的代码(如果我们将数组假装为一维,则为索引).
我还提供了使用引用或指针来显示差异的替代方法.
To complement my initial solution and as a response for other solutions and comment, I have provided a solution that reinterpret a two dimensional array as a single dimensional array.
This code is mainly for educational purpose. For real life program, using STL or boost would generally be recommanded.
Well in that solution, I have added code that will set each item to it global index modulo (the index if we would pretend the array to be single dimension).
I have also provides alternative using references or pointers to show the differences.
//void GetCodes(char *data, int count) // would works the same as next line
void GetCodes(char data[], int count)
{
for (int i = 0; i != count; ++i)
{
data[i] = static_cast<char>(i %256);
}
}
template<size_t M, size_t N>
void GetCodes(char (&data)[M][N])
{
// Any of these produce the same result.
GetCodes(reinterpret_cast<char(&)[M * N]>(data), M * N);
//GetCodes(*reinterpret_cast<char(*)[M * N]>(data), M * N);
}
template<size_t M, size_t N>
void GetCodes(char (*data)[M][N])
{
// Any of these produce the same result.
GetCodes(reinterpret_cast<char(&)[M * N]>(*data), M * N);
//GetCodes(*reinterpret_cast<char(*)[M * N]>(data), M * N);
//GetCodes(*reinterpret_cast<char(*)[M * N]>(*data), M * N);
}
int main()
{
char array1[100][8] = { 0 };
char array2[100][8] = { 0 };
GetCodes(array1); // Calls first template
GetCodes(&array2); // Calls second template
return 0;
}
这篇关于如何将数组维度作为模板函数的参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!