以下代码无法编译,我试图弄清楚如何计算传递给函数的数组的大小,似乎无法使语法正确。
我得到的错误是:
Error 1 error C2784: 'size_t getSize(T (&)[SIZE])' : could not deduce template argument for 'T (&)[SIZE]' from 'const byte []' 16 1 sizeofarray
以下是源代码:
#include <cstdint>
#include <stdio.h>
template<typename T, size_t SIZE>
size_t getSize(T (&)[SIZE]) {
return SIZE;
}
typedef std::uint_fast8_t byte;
void processArray(const byte b[])
{
size_t size = getSize(b); // <- line 16 where error occurs
// do some other stuff
}
int main(const int argc, const char* argv[])
{
byte b[] = {1,2,3,4,5,6};
printf("%u\n", getSize(b));
processArray(b);
return 0;
}
答案 0 :(得分:9)
如果你想要这个,你需要让processArray成为一个模板:
template <size_t size>
void processArray(const byte (&b)[size])
{
// do some other stuff
}
C ++不允许按值传递数组。如果你有这样的功能:
void f(int a[5]);
您可能看起来像是按值传递数组,但该语言有一个特殊规则,即该表单的参数只是另一种说法:
void f(int *a);
因此,数组的大小根本不属于类型。这是C中存在的行为。幸运的是,C ++有引用,你可以传递对数组的引用,如下所示:
void f(int (&a)[5]);
这样就可以保留数组的大小。
现在,唯一剩下的技巧是使函数通用,因此它可以在任何大小的数组上工作。
template <size_t n> void f(int (&a)[n]);
现在,可以自动为您生成引用不同大小数组的函数的新版本,并且可以通过模板参数访问该大小。
答案 1 :(得分:6)
作为函数的参数,const byte b[]
被视为const byte *b
。没有关于调用该函数的数组大小的编译时信息。
答案 2 :(得分:5)
要传递对数组的引用,您需要使processArray
成为模板并使用相同的技术。如果未传入引用,则参数为指针,指针类型不具有数组大小信息。
template<size_t size>
void processArray(const byte (&b)[size]) {
// ...
}
答案 3 :(得分:-1)
这是规范示例,为什么你应该使用像getSize
而不是sizeof
这样的函数模板来确定数组大小。
sizeof
,您已经获得了指针的大小而且没有更明智。错误是什么?它有一个函数参数const T arg[]
,并认为这意味着arg
是一个数组。不是。这是C语言中令人遗憾的语法,与<{em>完全等效到const T* arg
。 你得到一个指针。
这也是为什么有些人会错误地认为“数组是指针”的原因。他们不是。这只是这种特定的语法。