我的代码具有以下基本结构:
namespace A{
template<class T,unsigned DIM>
class CMyTable{
...
public:
template<class T,unsigned DIM>
friend std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec);
}
};
}
最初的问题是让我的运营商&lt;&lt;在命名空间A之外。
我尝试了这个解决方案:How do I define friends in global namespace within another C++ namespace?
namespace A{
template<class T,unsigned DIM>
class CMyTable;
}
template<class T,unsigned DIM>
std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec);
namespace A{
template<class T,unsigned DIM>
class CMyTable{
...
public:
template<class T,unsigned DIM>
friend std::ostream& ::operator<<(std::ostream& s, const CMyTable<T,DIM>& vec);
}
};
}
template<class T,unsigned DIM>
std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec){
// [...]
}
我收到此错误:错误C2063:'operator&lt;&lt;' :不是类声明中的函数。
public:
template<class T,unsigned DIM>
friend std::ostream& ::operator<<(std::ostream& s, const CMyTable<T,DIM>&
有没有人有任何想法?
感谢。
答案 0 :(得分:0)
输出操作符实际上是类的接口,所以,从逻辑上讲,它应该在名称空间中,声明类,但是为了让你的代码有效,你可以使用
namespace A{
template<class T,unsigned DIM>
class CMyTable;
}
// friend is not correct here.
template<class T,unsigned DIM>
/*friend*/ std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec);
namespace A{
template<class T,unsigned DIM>
class CMyTable{
...
public:
// choose another names of template pars.
// or use
//friend std::ostream& (::operator << <>)(std::ostream& s,
//const CMyTable<T, DIM>&);
/*template<class T,unsigned DIM>*/
template<class U, unsigned D>
friend std::ostream& (::operator <<)(std::ostream&,
const CMyTable<U,D>&);
};
}
template<class T,unsigned DIM>
std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec){
// [...]
}
答案 1 :(得分:0)
如果您的ostream重载必须是friend
(需要访问受保护成员),那么将其内联定义,以便您可以使用传递给该类的模板参数。
namespace A{
template<class T,unsigned DIM>
class CMyTable{
...
public:
// template<class T,unsigned DIM> // This will shadow otherwise
friend std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec) {
// [...]
}
};
}
否则完全从类和namesapce中删除它的声明,只是将它定义为模板化的重载。
请记住,如果它不需要访问私有或受保护的元素,则不必是朋友。
namespace A{
template<class T,unsigned DIM>
class CMyTable{
...
public:
};
}
template<class T,unsigned DIM>
std::ostream& operator<<(std::ostream& s, const A::CMyTable<T,DIM>& vec){
// [...]
}
第三个选项是让它保持友好,但在命名空间A中定义它
namespace A{
template<class T,unsigned DIM>
class CMyTable{
public:
int i;
template<class V,unsigned E>
friend std::ostream& operator<<(std::ostream& s, const CMyTable<V,E>& vec);
};
};
//
//
namespace A{
template<class T,unsigned DIM>
std::ostream& operator<<(std::ostream& s, const CMyTable<T,DIM>& vec) {
s << vec.i;
}
}