为什么以下有用?:
template<typename T> class example {
public:
T val;
example() {val=0;}
example operator+(example ob) {
example temp;
temp.val = val+ob.val;
return temp;
}
};
int main() {
example<int> a;
a+a;
return 0;
}
如果我没有看到它编译,我会说操作符重载应该如下:
example<T> operator+(example<T> ob {
example<T> temp;
temp.val = val+ob.val;
return temp;
}
另外,我尝试在main中更改以下内容:
example<int> a;
为:
example a;
但是错误地说“......缺少模板参数......” 我的猜测是,在类定义中,编译器将示例视为示例。但由于这只是一个猜测而我无法在任何地方确认,我想我会在这里问。
答案 0 :(得分:2)
是的,当你在模板定义中时,可以省略模板参数(但是,例如,不在main中,因为它在模板定义之外)。
省略时,参数将替换为当前实例化的参数。即当您将模板实例化为example<int>
时,模板定义中没有模板参数的example
的所有出现都将替换为example<int>
以进行该实例化。
从标准(C ++ 11,强调我的):
(14.6.2.1/1)名称是指当前实例化,如果它是
- 在类模板的定义中,类模板的嵌套类,类模板的成员或类模板的嵌套类的成员,类模板的注入类名(第9条)或嵌套类,
[...]
以后的几节,标准给出了一个例子:
template <class T> class A {
A* p1; // A is the current instantiation
A<T>* p2; // A<T> is the current instantiation
/*...*/
};
答案 1 :(得分:2)
这是因为injected-class-name
(来自9p2):
将类名插入到声明它的作用域中 看到类名后立即。类名也是 插入到类本身的范围内;这被称为 的注射类名强>
和14.6.1p1:
与普通(非模板)类一样,类模板也有 注入类名(第9条)。注入类名可以用作 模板名称或类型名称。与它一起使用时 template-argument-list,作为模板的模板参数 template-parameter,或者作为最终标识符 它是一个友元类模板声明的详细说明类型说明符 指的是类模板本身。 否则,相当于 template-name后跟类的模板参数 括在&lt;&gt;。
中的模板
inject-name-name引用类本身内的example<T>
,允许使用简写版本。
答案 2 :(得分:1)
如果我理解你的问题,是的,在类定义中,你不需要让每个函数都成为类模板参数的模板。
的确,如果你必须在课外定义函数,则需要如下所示。
template<typename T>
example<T> example<T>::operator+(example<T> ob) {
P.S。你应该将争论改为const example<T>& ob
以减少不必要的副本。