Обоснование
Я пытаюсь полностью исключить назначения в С++-коде. То есть я использую только инициализации и объявляю локальные переменные как const
, когда это возможно (т.е. Всегда, кроме переменных цикла или аккумуляторов).
Теперь я нашел случай, когда это не работает. Я считаю, что это общая картина, но, в частности, она возникает в следующей ситуации:
Описание проблемы
Позволяет сказать, что у меня есть программа, которая загружает содержимое входного файла в строку. Вы можете вызвать инструмент, указав имя файла (tool filename
) или используя стандартный поток ввода (cat filename | tool
). Теперь, как инициализировать строку?
Следующие действия не работают:
bool const use_stdin = argc == 1;
std::string const input = slurp(use_stdin ? static_cast<std::istream&>(std::cin)
: std::ifstream(argv[1]));
Почему это не работает? Поскольку прототип slurp
должен выглядеть следующим образом:
std::string slurp(std::istream&);
То есть аргумент я не const
и, как следствие, я не могу привязать его к временному. Кажется, что это не так, используя отдельную переменную.
Ужасное обходное решение
В настоящее время я использую следующее решение:
std::string input;
if (use_stdin)
input = slurp(std::cin);
else {
std::ifstream in(argv[1]);
input = slurp(in);
}
Но это тщетно меня неправильно. Прежде всего, это больше кода (в SLOC), но он также использует if
вместо (здесь) более логического условного выражения и его назначение назначения после объявления, которое я хочу избежать.
Есть ли хороший способ избежать этого непрямого стиля инициализации? Проблема может быть обобщена во всех случаях, когда вам нужно мутировать временный объект. Arent-потоки, плохо разработанные для того, чтобы справляться с такими случаями (поток const
не имеет смысла, и все же работа над временным потоком имеет смысл)?