使用迭代器作为参数重载 << 运算符

Overloading of << operator using iterator as a parameter

我想将枚举值打印为文本并用于重载。假设我有以下代码:

#include <iostream>
#include <map>
#include <string>
#include <vector>
#include <unordered_set>

enum enm{
    One,
    Two
};

class Complex{
public:
friend std::ostream& operator<<(std::ostream& out, std::unordered_multiset<int>::const_iterator i){
    switch (*i){
        case One:{
            return out<<"One";
        }
        case Two:{
            return out << "Two";
        }
    }
}
void func(std::unordered_multiset<int> _v);
};

void Complex:: func(std::unordered_multiset<int> _v){
    _v.insert(One);
    _v.insert(Two);
    for (std::unordered_multiset<int>::const_iterator i(_v.begin()), end(_v.end()); i != end; ++i){
        std::cout <<"Num: " << *i <<std::endl; //need to get here "One", "Two" instead of 0, 1
    }
}

int main(){
    Complex c;
    std::unordered_multiset<int> ms;
    c.func(ms);
    return 0;   
}

问题是这个变体不起作用。所以,我得到 0、1 而不是一、二。不知道如何正确地做。 谢谢你的帮助!

我假设您将 i 更改为 *i 以便您的程序能够编译。为了打印迭代器,您必须执行 i,但这会因编译器错误而失败。

问题在于插入运算符在其第一个声明中被定义为 class 中的友元,因此查找此运算符只能依赖于名称空间和与之关联的 classes参数类型,称为 ADL 或 Koenig 查找的查找。

由于 std::ostreamunordered_multiset::const_iterator 未与 Complex 相关联(请参阅 ADL#Details),查找无法找到插入运算符。

解决方案是在 class 之外声明函数,以便运算符的正常 unqualified lookup 发生:

std::ostream& operator<<(std::ostream&, std::unordered_multiset<int>::const_iterator);
class Complex { .. };

不过,我建议您 定义 运算符在 class 之外,因为它似乎不需要访问 private/protected 的成员Complex(与实体成为朋友的部分目的)。