在类模板内定义的友元函数.函数模板重定义错误

Friend function defined inside class template. Function template redefinition error

本文关键字:定义 函数 函数模板 错误 友元      更新时间:2023-10-16

下面是两个代码示例。第一个为类模板Vector定义了operator+(),而第二个只是声明了函数,但将函数定义移到了类体之外。第一个示例导致以下错误:

main.cpp(4): error C2995:
'Vector<L,T> operator +(const Vector<L,T> &,const Vector<L,T> &)' :
function template has already been defined

以下是我的问题:

  1. 为什么两个模板实例化在main()导致函数模板重定义错误?根据我的理解,它们应该导致唯一的实例,因为模板参数不同。
  2. 如何在类体之外移动函数定义来解决错误?

错误样例:

template<int L, typename T>
class Vector {
  template<int L, typename T> friend
  Vector<L, T> operator+(const Vector<L, T>& lhs, const Vector<L, T>& rhs) {
    return Vector<L, T>();
  }
private:
  T data[L];
};
int main() {
  Vector<42, double> v42d;
  Vector<24, int> v24i;
  return 0;
}

工作示例:

template<int L, typename T>
class Vector {
  template<int L, typename T> friend
  Vector<L, T> operator+(const Vector<L, T>& lhs, const Vector<L, T>& rhs);
private:
  T data[L];
};
template<int L, typename T>
Vector<L, T> operator+(const Vector<L, T>& lhs, const Vector<L, T>& rhs) {
  return Vector<L, T>();
}
int main() {
  Vector<42, double> v42d;
  Vector<24, int> v24i;
  return 0;
}

模板类型L和T是已知的,因此不需要重新引入。实际上,为友元函数这样做会使它们掩盖为类定义的函数。

修复:

template<int L, typename T>
class Vector {
    friend
    Vector<L, T> operator+(const Vector<L, T>& lhs, const Vector<L, T>& rhs) {
        return Vector<L, T>();
    }
private:
    T data[L];
};

相当于:

template<int L, typename T>
class Vector {
    friend
    Vector operator+(const Vector& lhs, const Vector& rhs) {
        return Vector();
    }
private:
    T data[L];
};