为什么必须在每个使用模板的函数之前声明模板?

Why does a template have to be declared before every function that uses one?

为什么下面的代码有效

template<class T>
T AddThree(T input)
{
    return input + 3;
}

template<class T>    // If I remove this line it won't compile
T SubtractThree(T input)
{
    return input - 3;
}

但是如果我注释掉指示它不会编译的行?为什么编译器在第一次声明时仍然不知道 template<class T>(就像文件正文中声明的任何其他内容一样)?

您可以将其视为函数签名的一部分。如果将完整的声明写在一行中,也许更容易看出联系:

template<class T> T AddThree(T input)
{
    return input + 3;
}

就像你需要为每个函数声明参数一样。你不会期望这会起作用:

std::string AddThree(std::string input)
{
    return input + "3";
}

std::string SomethingElse(input)
{
    // ...
}

在这里,与模板参数一样,您需要在第二个函数和第一个函数中声明 input。这是语言的范围规则:)

编译器如何知道 SubtractThree 是模板函数?显然,您不希望单个模板声明意味着 everything 后记是一个模板。您还可以想象设计 C++ 规范,使每个无法识别的 class(在本例中为 T)都被视为一个模板,但是当您拼错 classes.[=11= 时,您就有制作模板函数的风险]

注意声明终止符(分号或函数体)的位置。 template <class T> 本身不是一个声明——它不在整个文件的范围内。它是相关函数模板声明的一部分。