问题
I`d like to print enum values as text and use for it overloading. Suppose I have the following code:
#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;
}
The problem is this variant doesn`t work. So, I get 0, 1 instead of One, Two. Have no ideas how to do it properly. Thank you for help!
回答1:
I'm assuming you changed i
to *i
in order for your program to compile. In order to print the iterator you must do i
, but this fails with a compiler error.
The problem is that the insertion operator is defined as a friend within the class on its first declaration, so the lookup to find this operator can only depend on namespaces and classes associated with the argument types, a lookup referred to as ADL or Koenig lookup.
Since std::ostream
and unordered_multiset::const_iterator
are not asscoiated with Complex
(see ADL#Details), lookup fails to find the insertion operator.
The solution is to declare the function outside of the class so that normal unqualified lookup for the operator takes place:
std::ostream& operator<<(std::ostream&, std::unordered_multiset<int>::const_iterator);
class Complex { .. };
I would recommend however that you define the operator outside of the class, as it doesn't seem to need to access private/protected members of Complex
(part of the purpose of befriending entities).
来源:https://stackoverflow.com/questions/31119555/overloading-of-operator-using-iterator-as-a-parameter