这段代码做了什么以及为什么要编译?

时间:2013-01-14 11:52:58

标签: c++ oop class templates gcc

我正在用C ++创建一个Vector2类作为模板,我想将+运算符定义为非成员友元函数,可以简单地添加两个向量。

这是我的Vector2模板类中的朋友声明:

template <class U>
friend Vector2<T> operator+(const Vector2<T> &lhs, const Vector2<T> &rhs);

这包含在.hpp文件中,但实现位于单独的.cpp文件中:

template <class T>
Vector2<T> operator+(const Vector2<T> &lhs, const Vector2<T> &rhs)
{
    return Vector2<T>(lhs.x_ + rhs.x_, lhs.y_ + rhs.y_);
}

此编译没有任何警告,但似乎无效。

Vector2<int> v1(4, 3);
Vector2<int> v2(3, 4);

Vector2<int> v3 = v1 + v2;

当我尝试编译上面的代码片段时,GCC抱怨道:

prog.cpp: In function ‘int main(int, char**)’:
prog.cpp:26:28: error: no match for ‘operator+’ in ‘v1 + v2’

source/vector2.hpp:31:23: note: template<class U> Vector2<int> operator+(const Vector2<int>&, const Vector2<int>&)
source/vector2.hpp:31:23: note:   template argument deduction/substitution failed:
prog.cpp:26:28: note:   couldn't deduce template parameter ‘U’
prog.cpp:26:18: warning: unused variable ‘v3’ [-Wunused-variable]

我做错了什么?如何为模板类正确定义+运算符?

2 个答案:

答案 0 :(得分:5)

编译器清楚地说明了问题所在。它不能推导出模板参数'U'。 你的声明(.hpp文件)是错误的。应该是

template <class T>
friend Vector2<T> operator+(const Vector2<T> &lhs, const Vector2<T> &rhs);

答案 1 :(得分:3)

运算符的模板使用未使用的参数U。签名使用T代替,可能来自周围的类模板:

template <class U>
friend Vector2<T> operator+(const Vector2<T> &lhs, const Vector2<T> &rhs);

由于未使用U,编译器无法自动推断出它应该是什么类型并给出错误。

一致地使用模板参数,将任何模板的定义放在.hpp文件中,您应该没问题。