Шаблон кандидата проигнорирован: не удалось вывести аргумент шаблона 'T' - PullRequest
0 голосов
/ 05 августа 2020

Я знаю, что этот вопрос, вероятно, задавали раньше, но я новичок в шаблонах, и вот мой код:

HeaderFile.h

class Identity  {
    public:    
        template <typename T>
        T getFamilyMembers() {
            if(1) {
              return false;
            }
            std::string whatever = "Test";
            return whatever;
        }
};

Main. cpp

#include "HeaderFile.h"

int main() {
  Identity id;
  std::cout << id.getFamilyMembers() << "\n";
}

Компилятор выдает две ошибки,

Main.cpp:25:10: error: no matching member function for call to 'getFamilyMembers'
      id.getFamilyMembers();
      ~~~^~~~~~~~~~
HeaderFile.h:22:11: note: candidate template ignored: couldn't infer template argument 'T'
        T getFamilyMembers() {

1 Ответ

3 голосов
/ 05 августа 2020

Шаблоны работают не так.

Вызывающий указывает, что такое T. Когда T является типом возврата, тогда все операторы возврата в функции должны быть значением T или чем-то, что может быть неявно преобразовано в T. Сама функция не может определять, что такое T во время выполнения.

Кроме того, T известно во время компиляции. Вы не можете возвращать разные типы в разных ситуациях без помощь типа варианта, например std::variant.

Для каждого отдельного T создается полностью новая версия функции. Шаблонные функции, следовательно, используются, когда generi c алгоритм может применяться к нескольким типам. Например, простая реализация алгоритма «поменять местами два значения» может скопировать одно из значений во временную переменную:

void swap(int & a, int & b) {
    int temp = a;
    a = b;
    b = temp;
}

Но теперь нам нужно написать новую swap() функцию для каждого возможного типа. вещей, которые мы когда-либо хотим поменять местами! Введите шаблоны: мы пишем функцию один раз, как шаблон:

template <typename T>
void swap(T & a, T & b) {
    T temp = a;
    a = b;
    b = temp;
}

Теперь компилятор сделает всю работу за нас, создавая новые версии swap() всякий раз, когда он видит T, которое у него нет ' т перед.

В вашем конкретном случае, если вы хотите вернуть значение, которое может быть строкой, но может быть ничем, это то, для чего предназначен std::optional. В этом случае вы можете вернуть std::optional<std::string>. Вы также можете просто вернуть std::string и использовать пустую строку, чтобы указать, что членов семейства нет.

Учитывая, что имя функции подразумевает, что может быть возвращено несколько элементов, было бы разумнее иметь функция return std::vector<std::string>, а затем случай «без членов семьи» просто представлен как пустой вектор.

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