Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
DiffEreD
1427 / 764 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
#1

Вывод map через ostream_iterator<> - C++

24.10.2012, 21:05. Просмотров 1132. Ответов 15
Метки нет (Все метки)

Не могу понять, оператор вывода для pair перегрузил, а код не компилируется. Как правильно сделать? Вот небольшой пример:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
#include <sstream>
#include <algorithm>
#include <map>
std::ostream & operator<<(std::ostream & os, const std::pair<char, size_t> & p)
{
    os<<p.first;
    return os;
}
 
int main()
{
    using std::cout; using std::endl;
    std::stringstream ss("qwerty");
    std::map<char, size_t> mapOfChars;
    char ch;
    while (ss.get(ch))
        mapOfChars[ch]++;
    std::copy(mapOfChars.cbegin(), mapOfChars.cend(), std::ostream_iterator<std::pair<char, size_t> >(cout, " "));
    cout<<endl;
    system("pause");
    return 0;
}
Лучшие ответы (1)
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
diagon
Higher
1921 / 1187 / 49
Регистрация: 02.05.2010
Сообщений: 2,925
Записей в блоге: 2
24.10.2012, 21:07     Вывод map через ostream_iterator<> #2
Засуньте оператор в пространство имен std.
DiffEreD
1427 / 764 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
24.10.2012, 21:18  [ТС]     Вывод map через ostream_iterator<> #3
Цитата Сообщение от diagon Посмотреть сообщение
Засуньте оператор в пространство имен std
Не понял, он и так в std.
Kastaneda
Форумчанин
Эксперт С++
4259 / 2791 / 219
Регистрация: 12.12.2009
Сообщений: 7,120
Записей в блоге: 1
Завершенные тесты: 1
24.10.2012, 21:21     Вывод map через ostream_iterator<> #4
Когда компилятор ищет нужную функцию, он пользуется т.н. ADL (Argument - Dependent Lookup - поиск с учетом аргуменов). Суть его заключается в следующем - функция ищется в том пространстве имен, к которому относятся ее аргументы. Если бы ADL не существовало, то вместо :
C++
1
2
std::string s;
std::cout << s << std::endl;
нам приходилось бы писать такие чудовищные конструкции:
C++
1
std::operator << (std::operator << (std::cout, s), std::endl);
но этого делать не приходиться, поскольку cout, string и endl находятся в пространстве имен std, то функция operator<< ищется там же.

Цитата Сообщение от yuron_477 Посмотреть сообщение
Не понял, он и так в std.
С чего это?
DiffEreD
1427 / 764 / 95
Регистрация: 21.06.2011
Сообщений: 1,740
Записей в блоге: 2
24.10.2012, 21:56  [ТС]     Вывод map через ostream_iterator<> #5
Да, как то я этот момент опустил, впервые просто с таким столкнулся. Переделал на такое и заработало:
C++
1
2
3
4
5
6
7
8
namespace std
{
    ostream & operator <<(ostream & os, const pair<char, size_t> & p)
    {
        os<<p.first;
        return os;
    }
}
Спасибо за подсказку.
Jupiter
24.10.2012, 22:07
  #6

Не по теме:

Цитата Сообщение от Kastaneda Посмотреть сообщение
Когда компилятор ищет нужную функцию, он пользуется т.н. ADL
если б все так было просто( ЕМНИП там целый свод правил когда применяется ADL, а когда обычный поиск

gray_fox
What a waste!
1253 / 1136 / 54
Регистрация: 21.04.2012
Сообщений: 2,359
Завершенные тесты: 3
25.10.2012, 00:18     Вывод map через ostream_iterator<> #7
yuron_477, вообще добавлять что-либо в std запрещено, на сколько я помню.
Kastaneda
Форумчанин
Эксперт С++
4259 / 2791 / 219
Регистрация: 12.12.2009
Сообщений: 7,120
Записей в блоге: 1
Завершенные тесты: 1
25.10.2012, 09:06     Вывод map через ostream_iterator<> #8

Не по теме:

Цитата Сообщение от Jupiter Посмотреть сообщение
если б все так было просто( ЕМНИП там целый свод правил когда применяется ADL, а когда обычный поиск
Значит надо было написать - "Когда компилятор ищет нужную функцию, иногда он пользуется т.н. ADL"



Цитата Сообщение от gray_fox Посмотреть сообщение
yuron_477, вообще добавлять что-либо в std запрещено, на сколько я помню.
Просто не рекомендуется, но не запрещено. Но в данном случае это единственный вариант решения проблемы.
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
25.10.2012, 09:12     Вывод map через ostream_iterator<> #9
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Kastaneda, В корне неверно. Инъекции в namespace std ведут к неопределенному поведению программы.

17.6.4.2.1/1

The behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a
namespace within namespace std unless otherwise specified. A program may add a template specialization
for any standard library template to namespace std only if the declaration depends on a user-defined type
and the specialization meets the standard library requirements for the original template and is not explicitly
prohibited.181
Kastaneda
Форумчанин
Эксперт С++
4259 / 2791 / 219
Регистрация: 12.12.2009
Сообщений: 7,120
Записей в блоге: 1
Завершенные тесты: 1
25.10.2012, 09:31     Вывод map через ostream_iterator<> #10
Цитата Сообщение от ForEveR Посмотреть сообщение
Kastaneda, В корне неверно.
Что именно не верно? Я ж говорю, что не рекомендуется. Про UB я честно говоря не знал, но все же и так понятно, что в std:: лезть не надо.

Или ты про это?
Цитата Сообщение от Kastaneda Посмотреть сообщение
Но в данном случае это единственный вариант решения проблемы.
Это я прочитал в "Философия С++", автор Эккель, хороший автор.
Может в С++03 UB не было?
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
25.10.2012, 09:39     Вывод map через ostream_iterator<> #11
Kastaneda, Было. Не стоит использовать copy с std::map, ибо у пары нет оператора вывода. Есть несколько вариантов обхода и из них оператор вывода в поток в пространстве имен стд - самый плохой.
Kastaneda
25.10.2012, 09:42
  #12

Не по теме:

Цитата Сообщение от ForEveR Посмотреть сообщение
Kastaneda, Было
Ну тогда странно, что автор не упомянул об этом в своей книге. Ладно, теперь буду знать

ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
25.10.2012, 09:46     Вывод map через ostream_iterator<> #13
К слову о нескольких вариантах вывода

http://stackoverflow.com/questions/6...ut-for-stdpair
Kastaneda
Форумчанин
Эксперт С++
4259 / 2791 / 219
Регистрация: 12.12.2009
Сообщений: 7,120
Записей в блоге: 1
Завершенные тесты: 1
25.10.2012, 10:11     Вывод map через ostream_iterator<> #14
Выводов до можно сколько угодно написать, идея была сделать, чтоб так работало:
C++
1
2
std::pair<someType1, someType2> p;
std::cout << p;
ForEveR
Модератор
Эксперт С++
7958 / 4720 / 319
Регистрация: 24.06.2010
Сообщений: 10,525
Завершенные тесты: 3
25.10.2012, 10:30     Вывод map через ostream_iterator<> #15
Kastaneda, Это-то будет работать и без инъекций в std.) Не будет работать непосредственно std::copy. А для этого самый нормальный вариант - враппер над парой.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
25.10.2012, 10:34     Вывод map через ostream_iterator<>
Еще ссылки по теме:

Переделать программу что бы была через map C++
C++ Параметр шаблона ostream_iterator по умолчанию
C++ Как через map вывести объект определенного класса?
C++ Map: обращение к значению (класс) через []
C++ Ostream_iterator

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Kastaneda
25.10.2012, 10:34     Вывод map через ostream_iterator<>
  #16

Не по теме:

Ну да, чет тупанул

Yandex
Объявления
25.10.2012, 10:34     Вывод map через ostream_iterator<>
Ответ Создать тему
Опции темы

Текущее время: 21:11. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru