如何将外部定义的全局运算符声明为类的友元
类外定义的全局运算符声明为类友元的方法
你只需要按以下两步操作即可:
- 先对全局运算符做前置声明,如果是模板运算符需要同时声明模板结构
- 在类内部写友元声明,签名和外部定义的运算符完全匹配即可
以下用你给出的ring_buffer<T>的operator==场景做示例:
1. 前置声明依赖的模板与运算符
首先需要提前声明ring_buffer模板和对应的全局operator==模板,避免类内友元声明时编译器找不到对应符号:
// 前置声明ring_buffer模板 template <typename T> class ring_buffer; // 前置声明全局的operator==模板 template <typename T> bool operator==(typename ring_buffer<T>::const_iterator left, typename ring_buffer<T>::const_iterator right);
2. 类内写友元声明
因为运算符要访问的是const_iterator的私有成员m_it,所以友元声明需要写在const_iterator类内部,注意签名要和全局运算符完全匹配,模板运算符要标注对应模板实参:
template <typename T> class ring_buffer { public: class const_iterator { // 友元声明,匹配全局的operator==模板实例 friend bool operator==<T>(typename ring_buffer<T>::const_iterator left, typename ring_buffer<T>::const_iterator right); private: // 示例私有成员 int* m_it = nullptr; }; // ring_buffer的其他类实现 };
3. 类外定义全局运算符
直接按正常的全局函数定义写法写即可:
template <typename T> bool operator==(typename ring_buffer<T>::const_iterator left, typename ring_buffer<T>::const_iterator right) { return left.m_it == right.m_it; }
注意事项
- 友元声明的返回值、参数列表、const修饰符必须和外部全局运算符的定义完全一致,否则编译器会判定为两个不同的函数
- 如果是普通非模板的全局运算符,不需要前置模板,只需要提前声明函数原型,类内直接写对应的友元声明即可
- 这种方式声明的友元运算符和类内定义的友元运算符作用完全一致,都属于外层命名空间的全局符号
内容的提问来源于stack exchange,提问作者Bonita Montero
相关产品推荐
相关产品推荐

