#c #templates #return-type #overloading
#c #шаблоны #возвращаемый тип #перегрузка
Вопрос:
Я пытаюсь следующим кодом перегрузить простую функцию для работы с несколькими типами. Однако не удается скомпилировать. Может кто-нибудь, пожалуйста, сказать мне, что не так и как это исправить?
typedef struct str1_type
{
int f1;
int f2;
} STR1;
typedef struct str2_type
{
char f1[100];
char f2[100];
}STR2;
template <typename T1, typename T2>
T2 getFieldOffset(const T1amp; t, int i);
int main() {
STR1 str1;
STR2 str2;
int i = getFieldOffset(str1,0);
const char* test = getFieldOffset(str2,0);
}
template <typename T1, typename T2>
T2 getFieldOffset(const T1amp; t, int i)
{
switch (i) {
case 0:
return t.f1;
case 1:
return t.f2;
default:
{
cout << "Invalid index passed: i" << i << endl;
return null;
}
}
}
Вот сообщение об ошибке:
test2.cpp : В функции ‘int main()’:
test2.cpp: 73: ошибка: нет соответствующей функции для вызова ‘getFieldOffset(STR1 amp;, int)’
test2.cpp: 75: ошибка: нет соответствующей функции для вызова ‘getFieldOffset(STR2 amp;, int)’test2.cpp : В функции ‘T2 getFieldOffset(const T1amp;, int)’:
test2.cpp:90: ошибка: ‘null’ не был объявлен в этой области
Комментарии:
1. Ну, какое сообщение об ошибке вы получаете?
2. Только что обновлено с сообщением об ошибке. Извините, что пропустил это ранее
Ответ №1:
template <typename T1, typename T2>
T2 getFieldOffset(const T1amp; t, int i);
Из аргументов можно вывести только аргумент шаблона T1
, поэтому вы должны явно указать аргумент шаблона T2
в списке аргументов шаблона при выполнении вызова.
Однако, если вы используете шаблон функции в том виде, в каком он написан, вам придется предоставить аргументы для обоих параметров шаблона. Вы должны поменять местами позиции T1
и T2
в списке параметров шаблона, чтобы вам оставалось только указать T2
:
template <typename T2, typename T1>
T2 getFieldOffset(const T1amp; t, int i);
Или, с лучшими именами для параметров шаблона:
template <typename TReturn, typename T>
TReturn getFieldOffset(const Tamp; t, int i);
Теперь вы можете вызвать это как:
getFieldOffset<ReturnType>(str1,0);
Ответ №2:
Компилятор не может определить возвращаемые типы. Одна из причин заключается в том, что getFIeldOffset
может возвращать значение, которое не является int
, но преобразуется в int
. Вы должны указать, когда возвращаемый тип равен:
getFieldOffset<STR2,int>(str2,0);
Ответ №3:
Похоже, вам следует написать NULL вместо null, и все это будет работать нормально.
In function 'T2 getFieldOffset(const T1amp;, int)': test2.cpp:90: error: 'null' was not declared in this scope
Проблема в создании экземпляра шаблона, компилятор не смог создать экземпляр шаблона из-за неправильного ‘null’, поэтому он не рассматривает возможность использования вашего шаблона в качестве кандидата для вызова вашей функции.
Ответ №4:
int i = getFieldOffset(str1,0);
const char* test = getFieldOffset(str2,0);
getFieldOffset
это шаблон функции, который принимает аргумент двух типов. Но в приведенном выше коде вы не указали аргумент типа. Вы хотите, чтобы компилятор выводил их. Но компилятор может определить только тип параметра функции, а не тип возвращаемого значения. Отсюда ошибка.
Вы должны предоставить оба аргумента типа:
int i = getFieldOffset<STR1, int>(str1,0);
const char* test = getFieldOffset<STR2, char*>(str2,0);
Однако, если вы измените порядок типов в шаблоне функции на обратный, как
template <typename T1, typename T2>
T1 getFieldOffset(const T2amp; t, int i); //T1 (i.e 1st type) becomes returnType!!
Тогда вы можете указать только один тип, возвращаемый тип, при вызове функции; другой тип может быть выведен из аргумента функции:
int i = getFieldOffset<int>(str1,0);
const char* test = getFieldOffset<char*>(str2,0);