【发布时间】:2014-09-17 12:01:20
【问题描述】:
考虑以下简单的模板函数:
template <typename T>
int compare(const T& lhs, const T& rhs) {
if (lhs<rhs) {
return -1;
}
else if (rhs<lhs) {
return 1;
}
else {
return 0;
}
}
我的课程讲师解释说,当我们使用模板函数时,我们应该隐式或显式指定要绑定到模板参数的模板参数:
#include<iostream>
#include<string>
using std::cout;
using std::endl;
using std::string;
int main() {
// implicitly specifying that T is int
cout<<compare(2,3)<<endl;
// explicitly specifying that T is string
cout<<compare<string>(string("something"),string("another"))<<endl;
}
这个推导正确模板的过程称为“实例化”;实际的模板参数用于生成适当版本的特定实例(在本例中为函数),以便稍后在运行时运行。
他还提到实例化是“按需”发生的。例如,最后一个代码段将产生两个比较函数的实例,一个用于int,一个用于string。
这让我想知道,为什么编译器会抱怨这样的事情:
#include<iostream>
#include<string>
using std::cout;
using std::endl;
using std::string;
template <typename T>
int compare(const T& lhs, const T& rhs) {
if (lhs<rhs) {
return x; // deliberate compile-time error; x cannot be resolved
}
else if (rhs<lhs) {
return 1;
}
else {
return 0;
}
}
int main() {
// no calls for compare are made here
}
您会认为编译器不应该对上述编译时错误有任何问题,因为 compare 永远不会被实例化。但是,这不会编译...
由于没有提供模板参数,因此该模板函数据称对编译器没有任何意义(这是一个简单的比较函数,但请考虑一个严重依赖于模板参数类型的模板函数......)
那么究竟什么是“实例化”呢?
【问题讨论】:
-
在您的第一段中:当您的老师说“显式”时,他的意思不是“演绎”。模板类型推导是知道
T是什么的隐式方法。 (换句话说,不存在显式模板类型推导。) -
对不起,正确的短语是“指定,无论是隐含的还是明确的”......我会更正主帖。
-
如果将
x替换为lhs,则代码会编译。 -
如果你使用
<string>,你也不需要string("blah")。 -
@NeilKirk,我知道,这是为了演示目的...... :)