2013-12-16 91 views
1

我嘗試創建一個Set類(使用模板)。我得到的問題是當我嘗試超載運營商< <。我試着將我的函數定義爲類Set的朋友,但它不起作用。我得到這個錯誤: 錯誤: '的std ::集,性病::分配器>設置:: M_設定' 是私人爲模板類重載運算符<<。不可能獲得私人成員,即使有朋友關鍵字

這裏是我的代碼:

#ifndef GUARD_set_h 
#define GUARD_set_h 

#include <iostream> 
#include <array> 
#include <vector> 
#include <set> 
#include <string> 

using namespace std; 

template <class T> 
class Set 
{ 

public: 
Set() {} // est ce vraiment requis de l'écrire ? je pense qu oui mais a verif ou copy ? 

Set(const T arr[], size_t arr_sz) // voir si operator= n est pas mieu ou copy ? 
{ 
    for(size_t i = 0; i < arr_sz; ++i) 
     m_set.insert(arr[i]); 
} 

Set(const vector<T>& vec) 
{ 
    for(size_t i = 0; i < vec.size(); ++i) 
     m_set.insert(vec[i]); 
} 

Set(const set<T>& st) 
{ 
    m_set = st; 
} 

Set(const Set& set_to_copy) 
{ 
    m_set = set_to_copy.m_set; 
} 



void insert(const T& elem) 
{ 
    m_set.insert(elem); 
} 

void remove(const T& elem) 
{ 
    m_set.erase(elem); 
} 

size_t cardinality() const 
{ 
    return m_set.size(); 
} 

bool isEmpty() const 
{ 
    return m_set.empty(); 
} 

/** DEBUT OPERATORS **/ 

Set& operator +=(const Set& st) 
{ 
    for (typename set<T>::iterator it = st.m_set.begin(); it != st.m_set.end(); ++it) 
     m_set.insert(*it); 
    return *this; 
} 


template<class U> friend ostream& operator<<(ostream &, const Set<T> &); 

private: 
set<T> m_set; 
}; 


/** Non-Member Operators **/ 
template <typename T> 
Set<T> operator+(Set<T> st1, const Set<T>& st2) // Set Union 
{ 
    Set<T> set_to_copy(st1); 
    set_to_copy += st2; 
    return set_to_copy; 
} 

template <typename T> 
Set<T> operator -(Set<T> st1, const Set<T>& st2) // Union Complement 
{ 
    Set<T> set_to_copy(st1); 
    set_to_copy -= st2; 
    return set_to_copy; 
} 

template <class T> 
ostream& operator<<(ostream &out, const Set<T> &st) 
{ 
    for (typename set<T>::iterator it = st.m_set.begin(); it != st.m_set.end(); ++it) 
     out << ' ' << *it; 
    cout << '\n'; 
    return out; 
} 
#endif 

看來問題是,即時嘗試訪問分配器從默認設置類,但我真的不知道我在哪裏嘗試使用此... 有人知道如何正確使用它? Shoudl我重新定義了一個新的分配器? (如果可能的編號喜歡保持這種組織的代碼(這是一個學校的工作,所以我有條件尊重:/) 我新的C++和我從來沒有使用模板之前:/ 對不起,我的近似英語,已經感謝你的幫助:)

回答

3

你需要的朋友從改變:

template<class U> friend ostream& operator<<(ostream &, const Set<T> &); 

// use Set<U> instead of Set<T> 
template<class U> friend ostream& operator<<(ostream &, const Set<U> &);//U instead of T 

,因爲當你的朋友操作員Set<T> instea的Set<U> d和Set<int>(例如)具有實例你指的是operator <<對於int具體:

ostream& operator<<(ostream &, const Set<int> &){} 

和模板化版本是從上面的一個完全不同的功能:

template <class T> 
ostream& operator<<(ostream &, const Set<T> &){} 

編輯:這取決於你想要什麼,如果你想讓你的T型朋友成爲特定的運營商,那麼使用需要使用Set<T>併爲你的類型T(int,float或者你實例化的任何類型)聲明運算符。Set和used operator < <),而不是模板版本。如果你想製作模板版本的朋友,那麼你需要使用Set<U>

+0

@ 0x499602D2就可以了。 – Raxvan

+0

需要注意的是,這使得'Set'類模板的任何給定實例的運營商朋友的所有模板實例化。 – juanchopanza

1

你遇到的第一個問題是操作員不是正確的。您不希望以U的類型不能推導的操作員的模板,您可能打算讓第二個參數爲Set<U>,而不是Set<T>。這就是說,你可能最好不要結交一個模板運營商,而應該結交一個非模板函數,你可以在類定義裏面定義它。

template <typename T> 
class Set { 
//... 
    friend std::ostream& operator<<(std::ostream& o, const Set& s) { ... } 
}; 

其中,考慮到所有的成員函數都是內聯定義的,不應該是一個問題。

0

感謝你們這麼快回答:)更改爲這個

friend ostream& operator<<(ostream &, const Set<T> &);` 

不工作對我的情況,因爲(我認爲)我需要定義操作< <'作爲一個非成員函數。但另一個命題似乎工作得很好:

template<class U> friend ostream& operator<<(ostream &, const Set<U> &); 
相關問題