我正在尝试创建一个Set类(使用模板)。我得到的问题是当我尝试重载运算符<<。我尝试将我的函数定义为类Set的朋友,但它不起作用。我收到了这个错误: 错误:'std :: set,std :: allocator> 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类访问allocator,但我真的不知道我在哪里尝试使用它... 有人知道如何正确使用它吗? Shoudl我重新定义了一个新的分配器? (如果可能的话,我想保留这个代码组织(这是学校的工作,所以我有尊重的标准:/) 我是c ++的新手,我之前从未使用过模板:/ 对不起,我的近似英语,我已经感谢你的帮助了:))
答案 0 :(得分: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>
代替Set<U>
并且拥有Set<int>
实例的朋友运算符时(例如),您特别为int引用operator <<
:
ostream& operator<<(ostream &, const Set<int> &){}
和模板化版本与上面的版本完全不同:
template <class T>
ostream& operator<<(ostream &, const Set<T> &){}
编辑:这取决于你想要什么,如果你想让朋友为你的类型T特定的操作符,那么使用需要使用Set<T>
并为你的类型T声明操作符(int ,float或您实例化的任何类型设置和使用运算符&lt;&lt;),而不是模板化版本。如果您想制作模板版本的朋友,那么您需要使用Set<U>
答案 1 :(得分:1)
您遇到的第一个问题是操作员不是正确的操作员。您不希望在无法推导出U
的{{1}}类型中模板化运算符,您可能打算让第二个参数为U
,而不是Set<U>
。
话虽这么说,你可能最好不要与模板运算符交朋友,而是与非模板函数建立联系,你可以在类定义中定义它。
Set<T>
其中,考虑到所有成员函数都是内联定义的应该不是问题。
答案 2 :(得分:0)
谢谢你们这么快回答:)改为这个
friend ostream& operator<<(ostream &, const Set<T> &);`
不能处理我的情况,因为(我认为)我需要将operator&lt;&lt;`定义为非成员函数。但另一个命题似乎运作良好:
template<class U> friend ostream& operator<<(ostream &, const Set<U> &);