尝试在模板类中重载 / 运算符的 C++ 错误
Posted
技术标签:
【中文标题】尝试在模板类中重载 / 运算符的 C++ 错误【英文标题】:C++ Errors trying to overload the / operator in a templated class 【发布时间】:2014-05-10 03:22:28 【问题描述】:我正在尝试为我创建的模板类重载“+”、“-”和“/”运算符。 + 和 - 运算符完美运行,但 / 运算符重载给了我错误。
我正在使用 Visual Studio 2013
//Set.h
#pragma once
#include <iostream>
#include <vector>
using namespace std;
template<class T>
class Set
friend Set<T> operator+ <> (const Set& left, const Set& right); //works
friend Set<T> operator- <> (const Set& left, const Set& right); //works
friend Set<T> operator/ <> (const Set& left, const Set& right); //does not
public:
Set(int n)
numItems = n;
setItems();
Set()
numItems = 0;
setItems();
~Set();
void setItems();
void output();
private:
int numItems;
vector<T> set;
;
我想重载 / 运算符以确定intersection of two sets
定义:
//---------------- Overload intersection -----------------
template<class T>
Set<T> operator/(const Set<T>& left, const Set<T>& right)
bool putin = false;
Set<T> quotient;
// loops through left Set
for (int i = 0; i < left.set.size(); i++)
for (int j = 0; j < right.set.size(); j++)
//loops through right set
//checks if the item in left is in right set
// if it is, PUT IT IN the new set
if (left.set[i] == right.set[j])
putin = true;
if (putin)
quotient.set.push_back(left.set[i]);
putin = true;
return quotient;
这是我遇到的错误
Error 1 error C2143: syntax error : missing ';' before '<'
Error 2 error C2460: '/' : uses 'Set<T>', which is being defined
Error 3 error C2433: '/' : 'friend' not permitted on data declarations
Error 4 error C2238: unexpected token(s) preceding ';'
Error 5 error C2365: '/' : redefinition; previous definition was 'data variable'
Error 6 error C2904: '/' : name already used for a template in the current scope
Error 7 error C2460: '/' : uses 'Set<int>', which is being defined
【问题讨论】:
【参考方案1】:这很棘手,它被 C++ FAQ 条目覆盖。
我无法准确解释为什么您的编译器会出现错误。但是您的所有运算符的代码都不正确:如常见问题解答中所述,编译器认为您正在尝试 friend
非模板函数,但这不起作用,因为函数确实需要是模板函数才能接受Set<T>
。
FAQ 建议的解决方案是先声明模板函数,然后再将它们加为好友:
template<typename T> class Set;
template<typename T>
Set<T> operator+ (const Set<T>& left, const Set<T>& right);
template<typename T>
Set<T> operator- (const Set<T>& left, const Set<T>& right);
template<typename T>
Set<T> operator/ (const Set<T>& left, const Set<T>& right);
template<class T>
class Set
friend Set<T> operator+ <> (const Set<T>& left, const Set<T>& right);
friend Set<T> operator- <> (const Set<T>& left, const Set<T>& right);
friend Set<T> operator/ <> (const Set<T>& left, const Set<T>& right);
请注意,您需要使用Set<T>
,而不仅仅是原始代码中的Set
。
这是可行的,因为现在编译器知道我们在谈论函数模板,因此它可以在 friend
行中识别它们。
另一个可能的解决方案是,没有函数的前向声明:
template<class T>
class Set
template<class U>
friend Set<U> operator / (const Set<U>& left, const Set<U>& right);
template<class U>
friend Set<U> operator+ (const Set<U>& left, const Set<U>& right);
template<class U>
friend Set<U> operator- (const Set<U>& left, const Set<U>& right);
public:
// ...
您明确地将模板函数称为朋友。我不完全确定第二种方法是个好主意。
如果您的运算符具有“正常”语义,那么也许您可以一起避免这个问题,但根本不使用friend
s。如果你定义了成员函数operator+=
、operator-=
、operator/=
,它们对*this
进行操作,那么在类之外声明其他操作符很简单,它们无需成为朋友就可以委托给这些函数:
template<typename T>
Set<T> operator+ (Set<T> a, Set<T> const &b return a += b;
【讨论】:
以上是关于尝试在模板类中重载 / 运算符的 C++ 错误的主要内容,如果未能解决你的问题,请参考以下文章