3

I'm trying to overload the '+', '-', and '/' operators for a templated class i created. the + and - operators work perfectly, but the / operator overload is giving me errors.

I'm using 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;
};

I am wanting to overload the / operator to determine the intersection of two sets

Definition:

    //---------------- 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;
} 

Here are the errors i'm getting

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

4

1 回答 1

2

这很棘手,C++ FAQ条目涵盖了它。

我无法确切解释为什么你的编译器会给出它所犯的错误。但是所有运算符的代码都不正确:如常见问题解答中所述,编译器认为您正在尝试friend使用非模板函数,但这不起作用,因为函数确实需要是模板函数才能接受Set<T>.

常见问题解答建议的解决方案是先声明模板函数,然后再将它们加为好友:

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:
// ...

您明确地将模板函数称为朋友。我不完全确定第二种方法是个好主意。

如果您的运算符具有“正常”语义,那么也许您可以一起避免这个问题,但根本不使用friends。如果您定义对 进行操作的成员函数operator+=, operator-=,那么在类之外声明其他操作符很简单,这些操作符无需成为朋友即可委托给这些函数:operator/=*this

template<typename T> 
Set<T> operator+ (Set<T> a, Set<T> const &b} { return a += b; }
于 2014-05-10T04:27:31.220 回答