简体   繁体   English

函数模板的C ++奇怪类型转换错误

[英]C++ Weird Type Conversion Error wtih Function Template

I have these C++ codes: 我有这些C ++代码:

In "header1.h" 在“ header1.h”中

template <typename T>
int  f1(const T& t1) {
    return 0;
}

extern const int  p[];

in cpptests.cpp 在cpptests.cpp中

#include "header1.h"
int _tmain(int argc, _TCHAR* argv[])  {
    f1(p);
    return 0;
}

And in VC++2010, I got this compile error: 在VC ++ 2010中,出现了此编译错误:

c:\work\cpptests\cpptests\cpptests.cpp(10): error C2664: 'f1' : cannot convert parameter 1 from 'const int []' to 'const int (&)[1]'
          Reason: cannot convert from 'const int []' to 'const int [1]'
          There is no context in which this conversion is possible
  Generating Code...

Wny does the template function call convert p to const int (&)[1] ? 模板函数调用是否会将p转换为const int (&)[1]

The type of your variable p is "array of unknown bound of const int ". 变量p的类型是“ const int的未知边界数组”。 By C++11 8.3.5, "Functions", 根据C ++ 11 8.3.5,“函数”,

If the type of a parameter includes a type of the form [...] “reference to array of unknown bound of T ,” the program is ill-formed. 如果参数的类型包括形式为“对T的未知边界数组的引用”的类型,则程序格式错误。

Allow me a little mental excursion on why this makes sense: 请允许我稍微思考一下为什么这很有意义:

You may know that even if a type T is incomplete, the types T * and T & are complete types. 您可能知道,即使类型T不完整,类型T *T &都是完整类型。 C++ contains a curious mechanism by which the type of a variable may change by virtue of being completed . C ++包含一种奇怪的机制,通过这种机制,变量的类型可以通过完成而改变。 That is, you can declare a variable T x; 也就是说,您可以声明变量T x; which has incomplete type, but later complete the type in the variable's definition. 类型不完整,但稍后在变量的定义中完成类型。 For example, take T = int[] : 例如,取T = int[]

extern int a[];    // `a` has incomplete type "array of unknown bound of int"
int a[10];         // now `a` has complete type "array of 10 int"

However (cf. 3.9/6), suppose now that we have another variable of pointer type T * : 但是(参见3.9 / 6),现在假设我们还有另一个指针类型T *变量:

int (*p)[] = &a;   // `p` is a pointer to an array of unknown bound

The type of this variable is already complete, but the "array" part of it can never be completed. 此变量的类型已经完成,但是它的“数组”部分永远无法完成。 So even if a may eventually have a complete type, the type p can never change. 因此,即使a最终可能具有完整的类型,类型p也永远不会改变。 Its type will never become int (*)[10] . 它的类型永远不会成为int (*)[10] Both types are already complete, and the latter is not a completion of the former. 两种类型都已经完成,而后者不是前者的完成。

That means that you can never use p to access the entire array object as a whole. 这意味着您永远无法使用 p来访问整个数组对象。 You can still use p by decaying *p to a pointer to the first element of the array (note that *p is a perfectly fine lvalue; glvalues need not have complete types), but you can never see the whole array through p . 您仍然可以通过将*p衰减为指向数组第一个元素的指针来使用p (请注意*p是一个非常好的lvalue; glvalues不必具有完整的类型),但是您永远无法通过p看到整个数组。 (The same reasoning applies to T & .) (相同的理由适用于T & 。)

Since pointers and references to arrays of unknown bound have such limited utility, they are not allowed as function parameter types. 由于指向未知边界数组的指针和引用具有这种有限的用途,因此不允许将它们作为函数参数类型使用。 In your case, the deduced type is precisely an "array of unknown bound" type, and so the resulting program is ill-formed. 在您的情况下,推导类型恰好是“未知边界数组”类型,因此生成的程序格式错误。

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

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