如果之前有人提出这样的问题,我很抱歉,但无论我搜索多少都无法找到(有类似的问题,但似乎没有一个问题适用于我)。
我正在写一个模板化的类,一切正常,除非我尝试重载operator +。我尝试为不同的参数重载operator +两次,但编译器没有看到其中一个定义并给出了一个错误。这是代码:
Worker.h(我的一个主流作品,在这里实现了这个问题,因为它更容易看到):
#ifndef _WORKER_H
#define _WORKER_H
#include <string>
#include "Project.h"
using namespace std;
template <class T>
class Worker {
public:
Worker(const string &, Project &);
void Work(const int &);
const Worker & Worker::operator+(const int &); //Problem
const Worker & Worker::operator+(const string &); //Problem
string getName() const;
int getTime() const;
private:
string myName; //The name of the worker
Project & myProject;
int myTime; //Variable to keep track of how much the worker worked.
};
#include "Worker.cpp"
#endif
以及Worker.cpp的相关部分:
template <class T>
const Worker<T> & Worker<T>::operator+(const int & add)
{
cout << add;
return *this;
}
template <class T>
const Worker<T> & Worker<T>::operator+(const string & add)
{
cout << add;
return *this;
}
+
运算符现在没有做任何事情,问题是编译器只看到第一个声明的函数(在这种情况下使用参数int)。这些函数似乎也没有问题,因为如果我只尝试重载一次,那么它们都可以单独工作。我也可以在非模板类中使用它们(进行必要的更改)。
我认为这很简单,但由于我是模板的新手,我无法弄清问题是什么。
答案 0 :(得分:2)
您的方法存在一些问题,与模板无关。
首先您的运营商仅适用于一种操作订单:Worker<T> + int
和不 int + Worker<T>
第二次通常你会想要返回一个新的Worker实例,而不是通过引用返回this
,因为A+B
不应该修改A
或{{1 }}。
所以你可以做的是为不同的顺序定义非成员运算符:
B
等等。
请注意,对于应该影响对象状态的运算符,例如template <typename T>
Worker<T> operator+(int i, const Worker<T>& t) { }
template <typename T>
Worker<T> operator+(const Worker<T>& t, int i) { }
,+=
等,通常的方法是使用成员运算符并返回通过引用,因为在这些情况下它是完全合理的。
答案 1 :(得分:1)
这里有两件事,其中一件是你的问题
成员函数的返回类型不受类是模板这一事实的影响,因此operator+
返回Worker
的声明和返回Worker<T>
的定义不同。在类定义中,它们应该是:
const Worker<T> & operator+(const int &); //Problem
const Worker<T> & operator+(const string &); //Problem
在上面的代码中也改变的另一件事是你不需要在类声明中使用范围(Worker::
)