2015-06-29 4 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; 
} 

Проблема в том, что этот вариант не работает. Итак, я получаю 0, 1 вместо One, Two. Не имеют идей, как это сделать должным образом. Благодарим за помощь!

+1

В качестве примечания стороны: Не используйте '_' в качестве префикса переменной, который зарезервирован для внутренних реализаций реализации C++. –

ответ

3

Я предполагаю, что вы изменили i на *i, чтобы ваша программа могла компилироваться. Чтобы напечатать итератор, вы должны сделать i, но это не с ошибкой компилятора.

Проблема заключается в том, что оператор вставки определяется как друг в классе в первом объявлении, поэтому поиск этого оператора может зависеть только от пространств имен и классов, связанных с типами аргументов, поиск, называемый ADL или поиск Koenig.

С std::ostream и unordered_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. Вот почему я ошибаюсь, передавая итератор в качестве параметра. Итак, существуют ли какие-либо варианты для печати значений перечисления в виде текста из мультимножества с использованием перегрузки или нет? :) – user3856196

+1

@ user3856196 [Вот пример, который создает новую фазу форматирования для пользовательского вывода] (http://coliru.stacked-crooked.com/a/cada1d56a6898890). Включите его, используя 'os << print_alpha_num' и выключите его с помощью' os << no_print_alpha_num'. – 0x499602D2

+0

Большое вам спасибо! – user3856196

Смежные вопросы