C ++错误试图重载模板化类中的/运算符

时间:2014-05-10 03:22:28

标签: c++ operator-overloading template-classes

我正在尝试为我创建的模板化类重载'+',' - '和'/'运算符。 +和 - 运算符完美地工作,但/运算符重载给我错误。

我正在使用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 个答案:

答案 0 :(得分:1)

这很棘手,它由C++ FAQ条目覆盖。

我无法解释为什么你的编译器会给出错误。但是你的所有运算符的代码都是错误的:正如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:
// ...

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

如果您的运营商有&#34;正常&#34;那么语义也许你可以一起避免这个问题,但根本不能使用friend。如果您定义在operator+=上运行的成员函数operator-=operator/=*this,那么很容易声明委托给那些的类外的其他运算符功能而不需要成为朋友:

template<typename T> 
Set<T> operator+ (Set<T> a, Set<T> const &b} { return a += b; }