函数参数中缺少类型模板参数

时间:2013-01-09 03:12:30

标签: c++ class templates

为什么以下有用?:

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;

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

3 个答案:

答案 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以减少不必要的副本。