我是模板新手。在阅读其中一个教程时,我发现了以下声明:
我们有以下函数模板:
template<class T1, class T2>
void PrintNumbers(const T1& t1Data, const T2& t2Data)
{}
这样调用函数的:
PrintNumbers<double, double>(10, 100);
这将产生以下模板函数:
void PrintNumbers<double, double>(const double& t1Data, const T2& t2Data)
{}
但是如果我在我的程序中尝试确切的事情,它就不起作用并且会抛出很多错误:
template<class T1, class T2>
void PrintNumbers<double, double>(const double& t1Data, const T2& t2Data)
{}
int main()
{
PrintNumbers<double, double>(10, 100);
return 0;
}
但是如果我使用下面的函数模板而不是上面的函数模板,那么它就可以工作了:
template<class T1, class T2>
void PrintNumbers(const T1& t1Data, const T2& t2Data)
{}
我试图理解这个特定概念的方式有问题吗?
如果是这样,那到底是什么 void PrintNumbers<double, double>(const double& t1Data, const T2& t2Data)
意思以及如何使用它(在什么情况下)?
最佳答案
所以我认为这是一个理解模板语法细微差别的问题。
从编译器的角度来看,有几件事都非常不同:
- 模板
- 模板特化
- 模板实例化
对于结构、函数、typedef 等,所有这些事情都可能发生。
当你写作时
template<class T1, class T2>
void PrintNumbers(const T1& t1Data, const T2& t2Data)
{}
声明一个模板函数。在此之后,您可以使用符号 PrintNumbers
作为一个有两个参数的函数,它将实例化模板,创建一个相应的有两个参数的函数。
如果你只想要一个特定的版本,你可以根本不使用模板
void PrintNumber(const double &, const double &)
{}
这样就好了。
当你写的时候:
void PrintNumbers<double, double>(const double& t1Data, const T2& t2Data)
{}
这真的没有任何意义,会被编译器拒绝。当您将模板参数放在像这样的声明符之后时,它应该是模板特化。然而,
为此您必须使用关键字
template
,即使参数列表为空,如template<> void PrintNumbers<double, double>(const double& t1Data, const T2& t2Data) {}
必须事先声明模板。您只能对已经存在的模板进行特化,编译器不会只为您引入模板。我不能告诉你为什么,这就是它的工作原理。
通常,你应该使用模板的方式是
- 首先声明“完整”模板,使用
template< foo, bar, baz > my_function(A a, B b, ...) {}
- 可选地,添加一些偏特化,注意不要产生模棱两可的偏特化:
template<foo, bar> my_function<foo, bar, bar::baz_type>(A a, B b, ...) {}
- 现在根据需要实例化模板。
关于c++ - 函数模板语法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32263030/