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

时间:2015-06-29 15:23:56

标签: c++ c++11 stl operator-overloading

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

#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而不是一,二。不知道如何正确地做到这一点。 谢谢你的帮助!

1 个答案:

答案 0 :(得分:3)

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

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

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

解决方案是在类外部声明函数,以便为运算符执行正常的ADL#Details

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

我建议您定义类外的运算符,因为它似乎不需要访问Complex的私有/受保护成员(部分目的是交朋友)。