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

时间:2022-09-06 15:36:13

The following code doesn't compile, I am trying to figure out how to calculate the size of an array that is passed into a function and can't seem to get the syntax correct.

下面的代码没有编译,我正在尝试计算如何计算一个数组的大小,这个数组被传递到一个函数中,并且看起来不正确。

The error I am getting is :

我得到的错误是:

Error   1   error C2784: 'size_t getSize(T (&)[SIZE])' : could not deduce template argument for 'T (&)[SIZE]' from 'const byte []' 16   1 sizeofarray

Here is the source code:

这里是源代码:

#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 个解决方案

#1


9  

If you want this to work, you need to make processArray be a template as well:

如果您想让它工作,您需要使processArray也成为一个模板:

template <size_t size>
void processArray(const byte (&b)[size])
{
    // do some other stuff
}

C++ does not allow passing arrays by value. If you have a function like this:

c++不允许按值传递数组。如果你有这样的函数:

void f(int a[5]);

It may look like you are passing an array by value, but the language has a special rule that says a parameter of this form is just another way of saying:

看起来好像是按值传递数组,但是语言有一个特殊的规则,它说这个形式的参数就是另一种说法:

void f(int *a);

So the size of the array is not part of the type at all. This is behavior inhereted from C. Fortunately, C++ has references, and you can pass a reference to an array, like this:

所以数组的大小不是类型的一部分。这是C继承的行为。幸运的是,c++有引用,您可以将引用传递给数组,如下所示:

void f(int (&a)[5]);

This way, the size of your array is preserved.

这样,数组的大小就被保留了。

Now, the only remaining trick is to make the function generic, so it can work on any size array.

现在,唯一剩下的技巧是使函数通用,这样它就可以处理任何大小的数组。

template <size_t n> void f(int (&a)[n]);

Now, new versions of the function that take references to arrays of different sizes can be generated automatically for you, and the size can be accessed through the template parameter.

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

#2


6  

As the argument to a function, const byte b[] is treated just like const byte *b. There is no compile-time information about the size of the array that the function was called with.

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

#3


5  

To pass a reference to the array, you need to make processArray a template and use the same technique. If you don't pass in a reference, the parameter is a pointer, and pointer types don't have array size information.

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

template<size_t size>
void processArray(const byte (&b)[size]) {
    // ...
}

#4


-1  

This is the canonical example of why you should use a function template like getSize rather than sizeof, for determining array size.

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

  • With sizeof, you'd have gotten the size of a pointer and been none the wiser.
  • 如果使用sizeof,你会得到一个指针的大小,而不会更聪明。
  • But, this way, you get a compilation error to point out your mistake.
  • 但是,通过这种方式,您会得到一个编译错误来指出您的错误。

What was the mistake? It was having a function parameter const T arg[] and thinking that this means arg is an array. It's not. This is unfortunate syntax from C that is precisely equivalent to const T* arg. You get a pointer.

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

This is also why some people think — incorrectly — that "arrays are pointers". They are not. It's just this specific syntax.

这也是为什么有些人不正确地认为“数组就是指针”。他们不是。它只是特定的语法。

#1


9  

If you want this to work, you need to make processArray be a template as well:

如果您想让它工作,您需要使processArray也成为一个模板:

template <size_t size>
void processArray(const byte (&b)[size])
{
    // do some other stuff
}

C++ does not allow passing arrays by value. If you have a function like this:

c++不允许按值传递数组。如果你有这样的函数:

void f(int a[5]);

It may look like you are passing an array by value, but the language has a special rule that says a parameter of this form is just another way of saying:

看起来好像是按值传递数组,但是语言有一个特殊的规则,它说这个形式的参数就是另一种说法:

void f(int *a);

So the size of the array is not part of the type at all. This is behavior inhereted from C. Fortunately, C++ has references, and you can pass a reference to an array, like this:

所以数组的大小不是类型的一部分。这是C继承的行为。幸运的是,c++有引用,您可以将引用传递给数组,如下所示:

void f(int (&a)[5]);

This way, the size of your array is preserved.

这样,数组的大小就被保留了。

Now, the only remaining trick is to make the function generic, so it can work on any size array.

现在,唯一剩下的技巧是使函数通用,这样它就可以处理任何大小的数组。

template <size_t n> void f(int (&a)[n]);

Now, new versions of the function that take references to arrays of different sizes can be generated automatically for you, and the size can be accessed through the template parameter.

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

#2


6  

As the argument to a function, const byte b[] is treated just like const byte *b. There is no compile-time information about the size of the array that the function was called with.

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

#3


5  

To pass a reference to the array, you need to make processArray a template and use the same technique. If you don't pass in a reference, the parameter is a pointer, and pointer types don't have array size information.

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

template<size_t size>
void processArray(const byte (&b)[size]) {
    // ...
}

#4


-1  

This is the canonical example of why you should use a function template like getSize rather than sizeof, for determining array size.

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

  • With sizeof, you'd have gotten the size of a pointer and been none the wiser.
  • 如果使用sizeof,你会得到一个指针的大小,而不会更聪明。
  • But, this way, you get a compilation error to point out your mistake.
  • 但是,通过这种方式,您会得到一个编译错误来指出您的错误。

What was the mistake? It was having a function parameter const T arg[] and thinking that this means arg is an array. It's not. This is unfortunate syntax from C that is precisely equivalent to const T* arg. You get a pointer.

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

This is also why some people think — incorrectly — that "arrays are pointers". They are not. It's just this specific syntax.

这也是为什么有些人不正确地认为“数组就是指针”。他们不是。它只是特定的语法。