перегрузка типа возврата кода шаблона не компилируется. что не так

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