7

以下代码无法编译,我试图弄清楚如何计算传递给函数的数组的大小,并且似乎无法使语法正确。

我得到的错误是:

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;
}
4

4 回答 4

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]);

现在,可以为您自动生成引用不同大小数组的函数的新版本,并且可以通过模板参数访问大小。

于 2012-11-12T15:17:06.190 回答
6

作为函数的参数,const byte b[]被视为const byte *b. 没有关于调用函数的数组大小的编译时信息。

于 2012-11-12T15:15:15.463 回答
5

要传递对数组的引用,您需要制作processArray一个模板并使用相同的技术。如果不传入引用,则参数为指针,而指针类型没有数组大小信息。

template<size_t size>
void processArray(const byte (&b)[size]) {
    // ...
}
于 2012-11-12T15:17:21.627 回答
-1

这是为什么您应该使用函数模板getSize而不是sizeof确定数组大小的典型示例。

  • 使用sizeof,您将获得指针的大小并且变得更聪明。
  • 但是,这样,你会得到一个编译错误来指出你的错误。

错误是什么?它有一个函数参数const T arg[],并认为这意味着arg是一个数组。它不是。这是来自 C 的不幸语法,它完全等同const T* arg. 你得到一个指针。

这也是为什么有些人错误地认为“数组是指针”的原因。他们不是。这只是这种特定的语法。

于 2012-11-12T16:02:31.357 回答