数组是什么类型的?

时间:2015-09-01 18:56:48

标签: c++ c++11 c++14

我在参考以下代码

时提出这个问题
#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*是等价的。那么&aT**的类型如何不等同?

我试图向自己解释的方式是对象的数组类型是T (&) [N],类型为T的对象数组的类型是T (*) [N]。并且该标准允许从第一个(即从T (&a) [N]T*)进行隐式转换,但是当您获取数组的地址时,它不会隐式地从T (*) [N]转到{{{} 1}}。我对么?或者我是否错误地推断T**是什么?

此外,您如何阅读这样的语法含义。有没有我可以参考的文件?

谢谢!

1 个答案:

答案 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更好的转换序列,如果

         
        
    • S1S2的正确子序列(比较13.3.3.1.1定义的规范形式的转换序列,不包括   任何左值变换;身份转换序列被认为是任何非身份转换的子序列   序列)或,如果不是,

    •   
    • S1的排名优于S2的排名,或S1S2具有相同的排名,并可通过以下规则区分以下段落,或者,如果不是,

    •   
    • [..]

    •   
  •   

数组到指针的转换是一个左值转换,所以它从那个项目符号点中排除。因此,转换序列都不被认为是更好的,所以我们必须转移到其他的破坏者身上。然而,这两个函数都是模板,并且都不比另一个更专业。这就是为什么它含糊不清。

相关问题