2015-06-29 139 views
0

我想將枚舉值作爲文本打印並用於重載。假設我有以下代碼:使用迭代器作爲參數重載<<運算符

#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; 
} 

問題是此變體does not`t工作。所以,我得到0,1而不是1,2。不知道如何正確地做到這一點。 謝謝你的幫助!

+1

附註:不要使用'_'作爲變量前綴,這是爲C++實現內部保留的。 –

回答

3

我假設你將i更改爲*i以便讓程序編譯。爲了打印迭代器,您必須執行i,但是這會因編譯器錯誤而失敗。

問題在於插入操作符在其第一個聲明中被定義爲類中的朋友,所以查找此操作符只能依賴於與參數類型關聯的命名空間和類,查找被稱爲ADL或Koenig查找。

由於std::ostreamunordered_multiset::const_iterator不與Complex(請參閱ADL#Details)配合,因此查找無法找到插入運算符。

的解決方案是將類聲明之外的功能,使操作員正常unqualified lookup發生:

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

我不過建議你定義操作類之外,因爲它似乎並不需要訪問Complex的私有/受保護成員(這是友好實體的一部分目的)。

+0

聲明該類以外的功能是對問題的一部分的決定。 另一個是 - 迭代器作爲參數,它不是類Complex的一部分。據我所知,重載函數必須至少帶有一個Complex類型的參數。這就是爲什麼我錯誤地將迭代器作爲參數傳遞。那麼,是否有任何變種打印枚舉值作爲文本從multiset使用重載或不:)? – user3856196

+1

@ user3856196 [這是一個例子,爲自定義輸出創建一個新的格式化方面](http://coliru.stacked-crooked.com/a/cada1d56a6898890)。用'os << print_alpha_num'打開它,用'os << no_print_alpha_num'關閉。 – 0x499602D2

+0

非常感謝! – user3856196