Создание экземпляров шаблонов в C ++ - PullRequest
8 голосов
/ 20 сентября 2011

Я смущен тем, как C ++ создает экземпляр шаблона.У меня есть код:

template <class T, int arraySize>
void test1(T (&array)[arraySize])
{
    cout << typeid(T).name() << endl;
}

template<class T>
void test2(T &array)
{
    cout << typeid(T).name() << endl;
}

int main()
{
    int abc[5];
    test1(abc);
    test2(abc);
    return 0;
}

Вот мои вопросы:
1.Как размер массива abc передается в test1 (параметр arraySize)?
2. Как компилятор C ++ определяет тип T в двух шаблонах?

Ответы [ 4 ]

7 голосов
/ 20 сентября 2011
  1. Нет передачи параметров в обычном смысле, поскольку параметры шаблона разрешаются во время компиляции.
  2. И arraySize, и T выводятся из типа параметра array. Поскольку вы передаете int[5], arraySize и T становятся 5 и int, соответственно, во время компиляции.

Если, например, вы объявили int* abc = new int[5];, ваш компилятор заклинит в тот момент, когда вы попытаетесь вызвать test1(abc). Помимо простого несоответствия типов, int* не содержит достаточно информации, чтобы определить размер массива.

5 голосов
/ 20 сентября 2011

Это называется вычет аргумента шаблона .

Тип из abc на сайте вызова: int(&)[5], в котором объединены две информации: int и 5.И шаблон функции принимает аргумент типа T(&)[N], но аргумент на сайте вызова равен int(&)[5], поэтому компилятор определяет, что T равно int, а N равно 5.

Прочитайте это:

4 голосов
/ 20 сентября 2011

В test1 компилятор создает шаблон с T [arraySize], являющимся его формой.Когда вы вызываете test1 (abc), вы предоставляете входной аргумент типа int [5], которому автоматически соответствует сопоставитель шаблонов.

Однако, если вы должны написать

int n=10;
int *abc = new int[n];
test1(abc);
test1<int,n>(abc);

, тогдакомпиляция не удалась бы, и компилятор заявил бы, что у него нет шаблона, соответствующего вызову функции test1 (abc) или вызову функции test1 (abc).

Это потому, что размер abc теперьдинамически распределяется, и поэтому тип abc является указателем, который имеет другой тип, и, следовательно, ни один шаблон не может быть сопоставлен с двумя вышеуказанными вызовами.

В следующем коде показаны некоторые типы

#include <iostream>
using namespace std;

template <class T> void printName() {cout<<typeid(T).name()<<endl;}

int main()
{      
    printName<int[2]>();  //type = A2_i
    printName<int*>();     //type = Pi

    getchar();
    return 0;
}
0 голосов
/ 20 сентября 2011

Я бы также добавил к тому, что говорит Наваз: теория вывод типа .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...