Стандартная библиотека С++: как писать обертки для cout, cerr, cin и endl?

Мне не нравится 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;

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

Ответы

Ответ 1

Почему бы не

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

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

Ответ 2

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

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

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

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

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

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

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