候选模板被忽略:无法推断模板参数 'T'

Candidate template ignored: couldn't infer template argument 'T'

我知道之前可能有人问过这个问题,但我是模板的初学者,这是我的代码,

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() {

这不是模板的工作方式。

来电者指定T是什么。当 T 是 return 类型时,函数中的 all return 语句必须是一个 T 值,或者可以隐式转换的东西至 T。函数本身无法决定 T 在运行时是什么。

除此之外,T 在编译时 是已知的。 如果没有变体类型的帮助,你不能在不同的情况下 return 不同的类型像 std::variant.

对于每个不同的 T,都会创建一个 函数的全新版本。 因此,当 通用算法时使用模板函数 可以应用于多种类型。例如,“交换两个值”算法的简单实现可能会将其中一个值复制到临时变量:

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;
}

现在编译器将为我们完成工作,每当它看到以前没有的 T 时创建新版本的 swap()


在您的特定情况下,如果您想要 return 一个可能是字符串但可能什么都不是的值,这就是 std::optional 的用途。在这种情况下,您可以 return 和 std::optional<std::string>。您也可以只 return std::string 并使用空字符串来表示没有家庭成员。

鉴于函数的名称暗示可以 return 编辑多个项目,因此使用函数 return std::vector<std::string> 和“no family”可能更有意义members" 的情况被简单地表示为一个空向量。