为什么这个模板函数调用不在这个函数中?

时间:2012-11-12 15:12:42

标签: c++ arrays templates

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

我得到的错误是:

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 个答案:

答案 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你得到一个指针。

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