3

作成したテンプレート クラスの「+」、「-」、および「/」演算子をオーバーロードしようとしています。+ および - 演算子は完全に機能しますが、/ 演算子のオーバーロードによってエラーが発生します。

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

/ 演算子をオーバーロードして、2 つのセットの交点を決定したいと考えています。

意味:

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

4

1 に答える 1

2

これは注意が必要で、C++ の FAQエントリで説明されています。

コンパイラがエラーを出す理由を正確に説明することはできません。ただし、すべての演算子のコードが正しくありません。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:
// ...

テンプレート関数をフレンドとして明示的に参照する場合。この 2 番目のアプローチが適切かどうかは完全にはわかりません。

オペレーターが「通常の」セマンティクスを持っている場合、おそらくこの問題を一緒に回避できますが、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 に答える