重载运算符<<用于模板类.即使使用好友关键字也无法获得私人会员



我正在尝试创建一个Set类(使用模板so)。我遇到的问题是当我试图重载运算符<lt;。我试图将我的函数定义为类的朋友Set,但它不起作用。我收到了以下错误:错误:"std::set,std::allocater>set::m_set"是私有的

这是我的代码:

#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

问题似乎是我试图从默认的set类访问分配器,但我真的不知道我在哪里尝试使用它。。。有人知道如何正确使用它吗?我应该重新定义一个新的分配器吗?(如果可能的话,我想保留这个代码组织(这是一个学校作业,所以我有标准要尊重:/)我是c++新手,以前从未使用过模板:/对不起,伙计们,我的英语水平很高,我已经感谢你们的帮助了:)

您需要从以下位置更改好友:

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>而不是Set<U>做友元运算符,并且有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并使用运算符<<的任何类型),而不是模板版本。如果你想让模板化版本成为朋友,那么你需要使用Set<U>

您遇到的第一个问题是运算符不正确。如果您不希望在类型U中模板化运算符,而不能推导出U,您可能希望第二个参数是Set<U>,而不是Set<T>

话虽如此,你最好不要与模板运算符交朋友,而是与非模板函数交朋友,你可以在类定义中定义它。

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

考虑到所有成员函数都是内联定义的,这应该不是问题。

感谢你们这么快回答:)更改为此

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

不处理我的情况,因为(我认为)我需要定义运算符<lt`作为非成员函数。但另一个提议似乎很有效:

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

相关内容

最新更新