Как C++ выводит тип для шаблонов функций?
На самом деле я не подразумеваю на свой вопрос полного и исчерпывающего ответа, иначе меня можно просто отправить на cppreference читать это огромное чтиво. Когда-нибудь может и займусь этим, но в данный момент мой уровень английского не сильно позволяет это сделать. Но я хочу примерно представлять каким образом он решает выводить типы, а конкретно разберу мою проблему на примере:
#include <iostream>
template <typename T>
T** createarray(int n, int m) {
T** mas = new T*[n];
for (int i = 0; i < n; i++) {
mas[i] = new T[m];
}
return mas;
}
int main()
{
int n, m;
std::cin >>n >> m;
double **arr = createarray(n, m);
}
Хочу создать двумерный массив, при этом чтобы элементы массива могли быть произвольного типа. Но код, не комплируется и оно в целом понятно, почему. Я пытаюсь вызывать функцию, в которой как бы не понятно, что такое тип T. Если бы например функция была такого вида:
T** createarray(int n, int m, T another_argument) {
T** mas = new T*[n];
for (int i = 0; i < n; i++) {
mas[i] = new T[m];
}
return mas;
}
То в целом становится более понятно, что надо сначала разобраться, что за тип нам передали и этого же типа будет функция. Но все же в контексте double **arr = createarray(n, m) ВРОДЕ КАК понятно, что функция тоже должна быть double? Однако тут встает другая проблема, я же могу вывести тип функции допустим как int, а потом кастануть к double? получается неоднозначность, что я могу привести к любому типу и потом просто кастануть неявно. Однако, что если я передам какую-то более сложную структуру данных по типу string? vector? Такой неоднозначности в целом уже не будет. Однако ошибки комплияции данная идея не устранила. Хотя в целом данные мысли не очень имеют место ввиду того, что я не совсем уверен как C++ действительно пытается выводить типы. Он по факту их выводит с помощью аргументов? Есть ли какой-то способ заставить мою функцию работать без явного указания типа: double **arr = createarray<double>(n, m).
Ответы (1 шт):
Как вы уже заметили, на вывод аргументов не влияет то, как используется возвращаемое значение функции.
С единственным исключением - зашаблоненным operatorом преобразования:
template <typename T>
struct Helper
{
int m, n;
template <typename T>
operator T **()
{
// Тут код создания массива.
}
};
Helper CreateArray(int m, int n)
{
return {m, n};
}
Тогда double **arr = createarray(m, n); заработает.