1

为什么以下工作?

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;

但得到一个错误说“......缺少模板参数......”我的猜测是在类定义中,编译器将示例视为示例。但由于这只是一个猜测,我无法在任何地方确认,我想我会在这里问。

4

3 回答 3

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

  /*...*/
};
于 2013-01-09T03:15:41.520 回答
2

这是因为injected-class-name(来自 9p2):

类名被插入到在看到类名之后立即声明它的作用域中。类名也被插入到类本身的范围内;这被称为 注入类名

从 14.6.1p1 开始:

像普通(非模板)类一样,类模板有一个注入类名(第 9 条)。注入的类名可以用作模板名或类型名。当它与模板参数列表一起使用时,作为模板模板参数的模板参数,或作为朋友类模板声明的详细类型说明符中的最终标识符,它指的是类模板本身. 否则,它相当于模板名称后跟 <> 中包含的类模板的模板参数。

注入的类名是指example<T>允许简写版本的类本身的内部。

于 2013-01-09T03:17:39.597 回答
1

如果我正确理解您的问题,是的,在类定义中,您不需要将每个函数都设为类模板参数的模板。

实际上,如果您必须在类之外定义函数,则需要如下所示。

template<typename T>
example<T> example<T>::operator+(example<T> ob) {

ps你应该改变论点const example<T>& ob以减少不必要的副本。

于 2013-01-09T03:16:01.443 回答