C++ 为什么';此模板函数调用是否在此函数内工作?

C++ 为什么';此模板函数调用是否在此函数内工作?,c++,arrays,templates,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> #inc

下面的代码没有编译,我试图找出如何计算传递到函数中的数组的大小,但似乎无法获得正确的语法

我得到的错误是:

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;
}
#包括
#包括
模板
尺寸(t(&)[size]){
返回大小;
}
typedef std::uint_fast8_t字节;
无效processArray(常量字节b[]
{

size\u t size=getSize(b);//作为函数的参数,
const byte b[]
的处理方式与
const byte*b
的处理方式相同。没有关于调用函数的数组大小的编译时信息。

如果要实现此功能,还需要将processArray设置为模板:

template <size_t size>
void processArray(const byte (&b)[size])
{
    // do some other stuff
}
看起来可能是按值传递数组,但该语言有一个特殊规则,表示这种形式的参数只是表示以下内容的另一种方式:

void f(int *a);
<> p>所以数组的大小根本不是类型的一部分。这是C继承的行为。幸运的是,C++有引用,并且可以将引用传递给数组,例如:

void f(int a[5]);
void f(int (&a)[5]);
这样,就保留了数组的大小

现在,剩下的唯一诀窍是使函数通用,这样它就可以在任何大小的数组上工作

template <size_t n> void f(int (&a)[n]);
模板无效f(int(&a)[n]);

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

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

template<size_t size>
void processArray(const byte (&b)[size]) {
    // ...
}
模板
无效processArray(常量字节(&b)[大小]){
// ...
}

这是一个典型的例子,说明了为什么应该使用函数模板,如
getSize
,而不是
sizeof
,来确定数组大小

  • 有了
    sizeof
    ,您就可以得到指针的大小,而且一点也不明智
  • 但是,通过这种方式,您会得到一个编译错误来指出您的错误
错误是什么?它有一个函数参数
const T arg[]
,并认为这意味着
arg
是一个数组。它不是。这是C的不幸语法,它正好等价于
const T*arg
。你得到了一个指针


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

您需要将
processArray
制作成一个模板。这是因为数组会衰减为指针。@dasblinkenlight-从技术上讲,数组的名称会衰减为指向其第一个元素的指针。数组不会衰减。@Vaughto-不,区别恰恰在于数组的名称会衰减s、 在大多数情况下,它是指向其第一个元素的指针。这是古老的C语言,它可以编写以数组为参数的函数,而不必为不同大小的数组复制代码。
strcpy
,例如,不需要知道它复制的数组的大小。@PeteBecker:我指的是第4.2.1节C++03标准中,该标准规定“类型为'array of nt'或'array of unknown bound of T'的左值或右值可以转换为类型为'pointer to T'的右值。结果是指向数组的第一个元素的指针。”顺便说一句,
const byte b[8]
也被当作
const byte*b
@JarrodRoberson:啊--我已经添加了一些解释。让我知道这是否清楚。很棒的解释,我希望我能投票并两次接受这个答案!