0

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
  • 1
    As a side note: Don't use _ as variable prefix, that's reserved for c++ implementation internals. Commented Jun 29, 2015 at 15:29

1 Answer 1

3

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).

Sign up to request clarification or add additional context in comments.

2 Comments

Declare the function outside of the class is a decision for one part of the problem. Another is -- iterator as a parameter, which is not a part of class Complex. As I understand, overloading function must take at least one argument that is of Complex class type. Thats why Im wrong passing iterator as a parameter. So, are there any variants to print enum values as text from multiset using overloading or not?:)
@user3856196 Here's an example that creates a new formatting facet for custom output . Turn it on using os << print_alpha_num and off with os << no_print_alpha_num.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.