简体   繁体   English

c++ 传递给模板请求数组指针的固定大小数组的类型错误

[英]c++ Type error for fixed-size array being passed to template requesting array pointer

I have a template function like the following:我有一个模板函数,如下所示:

template<typename T>    
T foo(byte* &buffer){
   ...
}

When I try to access it with a fixed-size array I get an error:当我尝试使用固定大小的数组访问它时,出现错误:

byte buffer[100] = {};
foo<int>(buffer);

However, when I create a new variable from buffer and pass that, no error:但是,当我从缓冲区创建一个新变量并传递它时,没有错误:

byte buffer[100] = {};
auto b = buffer;
foo<int>(b);

What is the type of buffer ? buffer的类型是什么? Is it not a byte* ?它不是一个byte*吗? Is there a way to cast it to a byte* ?有没有办法将它转换为byte* This only happens with a template function, otherwise it works as expected.这只发生在模板函数中,否则它会按预期工作。

The error in the first case is because the array buffer does not decay because you have passed it be reference.第一种情况的错误是因为数组buffer不会衰减,因为您已将其作为引用传递。 That is you cannot bind a reference to a pointer to byte to an array of byte.也就是说,您不能将指向字节的指针的引用绑定到字节数组。

While in the second case b is a pointer which you can pass by reference.而在第二种情况下, b是一个可以通过引用传递的指针。

Solution 1解决方案1

One way to solve this is by removing the reference from the function parameter ie, by the argument by value.解决这个问题的一种方法是从函数参数中删除引用,即通过值的参数。 So passing by value looks like:所以按值传递看起来像:

template<typename T>    
T foo(byte* buffer){//note pass by value
   ...
}

Note in solution 1 you can modify the array from inside the function through the pointer.请注意,在解决方案 1 中,您可以通过指针从函数内部修改数组。 One disadvantage of solution 1 is that here you can also pointer other pointers(like pointer to int) so you have to take care by yourself that you don't try to access anything that is out of bound of the array.解决方案 1 的一个缺点是,在这里您还可以指向其他指针(例如指向 int 的指针),因此您必须自己注意不要尝试访问超出数组范围的任何内容。 Other alternative would be to just pass the array by reference as you originally intended as shown in Solution 2.其他替代方法是按照您最初的意图通过引用传递数组,如解决方案 2 所示。

Solution 2 Pass the array by reference解决方案2通过引用传递数组

template<typename T,  std::size_t N>
T foo(byte (&buffer)[N])//this time you're passing the actual array by reference and not the pointer to its first element
{
}

Now in solution 2 you have passed the array by reference and you can modify it directly inside the function template.现在在解决方案 2 中,您已经通过引用传递了数组,您可以直接在函数模板中修改它。 Now foo<int>(buffer);现在foo<int>(buffer); will work.将工作。

The issue has nothing to do with templates.该问题与模板无关。 Change foo to a non-template void foo(byte* &buffer) and you will see the same error.foo更改为非模板void foo(byte* &buffer) ,您将看到相同的错误。

buffer as declared in the function is of type non-const reference to a pointer to byte .函数中声明的buffer指向byte指针的非常量引用类型。 In your second write-up, buffer is of type byte[100] with an l-value category.在您的第二篇文章中, buffer的类型为byte[100] ,具有左值类别。 When assigned to b , decay happens and b is of type byte* with an l-value category.当分配给b ,会发生衰减并且b是具有左值类别的byte*类型。 So b can be passed to foo without error.所以b可以foo地传递给foo Non-const reference can be bound to a non-const l-value.非常量引用可以绑定到非常量左值。 Your first write-up does not work this way.您的第一篇文章不会以这种方式工作。 Two simple fixes.两个简单的修复。

  1. Change to T foo(byte* buffer) .更改为T foo(byte* buffer) This way, when passing buffer to foo , decay happens first, resulting in an r-value of type byte* (thinking about it as an unnamed temporary intermediate result) be passed to foo by value and that is okay.这样,当将buffer传递给foo ,衰减首先发生,导致byte*类型的 r 值(将其视为未命名的临时中间结果)按值传递给foo ,这没问题。
  2. Change to T foo(byte* const buffer) .更改为T foo(byte* const buffer) Again, decay happens first, and const reference can be bound to an r-value, whereas non-const reference cannot .同样,衰减首先发生, const 引用可以绑定到 r 值,而非常量引用不能

If you prefer, may also declare buffer in foo to be of type non-const reference to byte[100] .如果您愿意,也可以将foo buffer声明为对byte[100]非常量引用类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM