我在参考以下代码
时提出这个问题#include <iostream>
using namespace std;
class A {
void foo(){}
};
template <typename T>
void func(T (&a) [1]) {cout << "In array type" << endl;}
template <typename T>
void func(T (*a) [1]) {cout << "In pointer to array type " << endl;}
template <typename T>
void func(T* a) {cout << "in pointer type" << endl;}
template <typename T>
void func(T** a) {cout << "In pointer pointer type" << endl;}
template <typename T>
void func(...) {}
int foo(int a) {return 1;}
int foo1() {return 1;}
int main() {
A a[1];
func<A>(&a);
return 0;
}
阵列的类型是什么?从下面的代码我可以看出,当你使用&
运算符获取数组的地址时,函数调用将解析为T (*a) [1]
的函数并且调用不是模糊的,但是当我更改时代码如下
#include <iostream>
using namespace std;
class A {
void foo(){}
};
template <typename T>
void func(T (&a) [1]) {cout << "In array type" << endl;}
template <typename T>
void func(T (*a) [1]) {cout << "In pointer to array type " << endl;}
template <typename T>
void func(T* a) {cout << "in pointer type" << endl;}
template <typename T>
void func(T** a) {cout << "In pointer pointer type" << endl;}
template <typename T>
void func(...) {}
int foo(int a) {return 1;}
int foo1() {return 1;}
int main() {
A a[1];
func<A>(a); // <-- CHANGE HERE
return 0;
}
我收到一个错误,说该函数的调用是不明确的。所以假想的type_of(a)
和T*
是等价的。那么&a
和T**
的类型如何不等同?
我试图向自己解释的方式是对象的数组类型是T (&) [N]
,类型为T
的对象数组的类型是T (*) [N]
。并且该标准允许从第一个(即从T (&a) [N]
到T*
)进行隐式转换,但是当您获取数组的地址时,它不会隐式地从T (*) [N]
转到{{{} 1}}。我对么?或者我是否错误地推断T**
是什么?
此外,您如何阅读这样的语法含义。有没有我可以参考的文件?
谢谢!
答案 0 :(得分:6)
......对象的数组类型是
T (&) [N]
...
没有。数组的类型是T[N]
。 a
的类型为A[1]
。您所描述的是数组的引用,您的原始示例涉及将指针传递给类型为A(*)[1]
的数组。您遇到的另一个规则是数组可以衰减为指针。换句话说,类型T[N]
的对象可以隐式转换为类型T*
的对象。
由于您的第二个示例失败的隐式转换。相关的重载只是:
template <typename T> void func(T (&)[1]); // (1)
template <typename T> void func(T* ); // (2)
两种重载都是可行的。第一个是完全匹配,而第二个是数组到指针的转换。但根据[over.ics.rank]中的表格,确定哪个可行候选者更好的方法包括选择转换序列:
标准转换序列
S1
是一个比标准转换序列S2
更好的转换序列,如果
S1
是S2
的正确子序列(比较13.3.3.1.1定义的规范形式的转换序列,不包括 任何左值变换;身份转换序列被认为是任何非身份转换的子序列 序列)或,如果不是,
S1
的排名优于S2
的排名,或S1
和S2
具有相同的排名,并可通过以下规则区分以下段落,或者,如果不是,[..]
数组到指针的转换是一个左值转换,所以它从那个项目符号点中排除。因此,转换序列都不被认为是更好的,所以我们必须转移到其他的破坏者身上。然而,这两个函数都是模板,并且都不比另一个更专业。这就是为什么它含糊不清。