Стандартная библиотека C ++: Как написать обертки для cout, cerr, cin и endl? - PullRequest
16 голосов
/ 21 мая 2010

Мне не нравится using namespace std, но я также устал от необходимости набирать std:: перед каждым cout, cin, cerr и endl. Итак, я подумал дать им более короткие новые имена, такие как:

// STLWrapper.h

#include <iostream>
#include <string>

extern std::ostream& Cout;
extern std::ostream& Cerr;
extern std::istream& Cin;
extern std::string&  Endl;

// STLWrapper.cpp

#include "STLWrapper.h"

std::ostream& Cout = std::cout;
std::ostream& Cerr = std::cerr;
std::istream& Cerr = std::cin;
std::string _EndlStr("\n");
std::string& Endl = _EndlStr;

Это работает. Но есть ли проблемы в вышеперечисленном, которые мне не хватает? Есть ли лучший способ добиться того же?

Ответы [ 2 ]

84 голосов
/ 21 мая 2010

Алекс дал вам ответ о том, как синтаксически решить эту проблему. Тем не менее, я хочу указать на два других аргумента относительно этой проблемы:

  1. Независимо от того, используете ли вы с использованием директивы (using namespace std) или его младшую злую сестру, с использованием декларации (using std::cout), перегрузка может привести к неприятным сюрпризам. Набирать std:: не составит большого труда по сравнению с , потратившими половину ночи на отладку , чтобы выяснить ваш код с именем std::distance() вместо собственной distance() функции только потому, что вы допустили небольшую ошибку, и std::distance() случайно стал лучшим матчем.

  2. Строка кода записывается один раз , но - в зависимости от времени жизни - читается десятки, сотни, а некоторые даже тысячи раз . Так что время, необходимое для написания строки кода, вообще не имеет значения , важно только время, необходимое для чтения и интерпретации строки кода . Даже если для написания строки со всеми правильными значениями std:: потребуется в три раза больше времени, если чтение ускоряется только на 10%, это все равно стоит.
    Поэтому важный вопрос: Легче ли читать и интерпретировать строку кода со всеми std:: на месте или сложнее ? От другой ответ :

    Вот еще один момент данных: много-много лет назад я также находил, что меня раздражает необходимость добавлять все префиксы из стандартной библиотеки к std::. Затем я работал в проекте, где с самого начала было решено, что директивы и объявления using запрещены, за исключением областей действия функций. Угадай, что? Большинству из нас потребовалось очень несколько недель, чтобы привыкнуть к написанию префикса, и спустя еще несколько недель большинство из нас даже согласилось с тем, что это фактически делает код более читабельным . (Есть причина для этого: Если вы любите более короткую или длинную прозу, это субъективно, но префиксы объективно добавляют ясности к коду. Не только компилятор, но вы тоже найдете легче понять, какой идентификатор упоминается.)

    За десятилетие этот проект вырос до нескольких миллионов строк кода. Поскольку эти обсуждения возникают снова и снова, мне однажды было любопытно, как часто (разрешенная) область действия функции using фактически использовалась в проекте. Я нашел источники для него и нашел только одно или два десятка мест, где он использовался. Для меня это означает, что, однажды попробовав, разработчики не сочли std:: достаточно болезненным , чтобы использовать использование директив даже один раз каждые 100kLoC даже там, где это было разрешено использовать .

    Мне грустно, что все книги и учебники, которые вы найдете, пропускают std::, потому что это заставляет людей привыкать так читать код. Когда я преподавал C ++ в течение нескольких лет (после вышеупомянутого опыта), я сказал своим ученикам, что не хочу видеть директивы или декларации using в их коде. (Единственное исключение из этого правила - using std::swap, кстати, вам понадобится, чтобы swap(a,b) принимал перегрузки за пределами пространства имен std.) Как только они привыкли, они не возражали и Когда их спросили об этом, они сказали, что находят код без префикса std:: сбивающим с толку. Некоторые даже добавили префикс std:: к коду, который они набрали из книги или учебника, в которых его не было .

Итог: что такого сложного в наборе std::, что каждый так взволнован? К настоящему времени я занимаюсь этим> 15 лет, и я совсем не скучаю по using.

59 голосов
/ 21 мая 2010

Почему бы не

using std::cin;
using std::cout;

и так далее? Затем в своем коде вы можете использовать cin, cout и т. Д., Не вставляя случайно все остальное пространство имен std в ваш код.

...