跳过模板参数

时间:2014-10-24 17:44:15

标签: c++

为什么我允许跳过模板参数(参见评论)?为什么我会收到链接错误?

template <typename T>
class Number {
public:
    Number(int val) {}

    // Why can I skip template arguments here?
    friend Number operator* (Number first, Number second);
};

template<typename T>
Number<T> operator* (Number<T> lhs, Number<T> rhs) {
    return Number<T>(42);
}

int main() {
    Number<int> num1(22), num2(23);
    Number<int> res = num1 * num2;
}

2 个答案:

答案 0 :(得分:3)

  1. 只有在其名称出现在该类的范围内时,才能省略类模板的模板参数。因此,您的friend声明隐含地需要两个Number<T>参数,但请注意它是模板。

  2. 由于它不是模板,因此您在T的实例化中指定的两个Number<T>参数中的int实际上是num1 num2。因此,您的friend声明实际上是:

    friend Number operator* (Number<int> first, Number<int> second);
    
  3. Number下面的函数模板的定义是一个单独的重载,而不是您声明为朋友的重载。这是因为第一个是带有两个Number<int>的常规函数​​,而第二个是可以用任何Number<T>实例实例化的函数模板。由于它是一个单独的重载,因此Number的朋友,因此无法访问Number的私人/受保护成员。

  4. num1 * num2选择呼叫您的常规朋友功能,因为两个参数完全匹配。由于尚未定义该函数,因此您将收到未定义的引用。

答案 1 :(得分:0)

因为您处于模板类的范围内。

该类使用type参数进行实例化,并且在该范围内,名称Number实际上是Number<T>,其分配器类型为T。

请注意,构造函数也不需要模板参数。

Number的friend运算符将实例化为:

 friend Number<int> operator* (Number<int> first, Number<int> second);