mardi 1 septembre 2015

What type is an array?

I am asking this question with reference to the following code

#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;
}

What is the type of an array? From the following code I can tell that when you take the address of an array with the & operator the function call resolves to the one with T (*a) [1] and the call is not ambiguous, but the when I change the code to the following

#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;
}

I get an error, saying that the call to the function is ambiguous. So the imaginary type_of(a) and T* are equivalent. How then are the types of &a and T** not equivalent?

The way I am trying to explain this to myself is that the type of an array to objects is T (&) [N] and the type of an array of objects of type T is T (*) [N]. And that the standard allows implicit conversion from the first (i.e. from T (&a) [N] to T*) but when you take the address of an array it does not implicitly go from a T (*) [N] to a T**. Am I correct? Or am I inferring what T (*) [N] is wrongly?

Further how do you go about reading the meaning of syntax like this. Is there a document I can refer to?

Thanks!

Aucun commentaire:

Enregistrer un commentaire