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:啊--我已经添加了一些解释。让我知道这是否清楚。很棒的解释,我希望我能投票并两次接受这个答案!