Итак, у меня есть следующая функция:
void scan(std::istream& is, Handler& h);
Я хочу называть это по-разному, например:
scan(std::cin, Handler());
scan(std::ifstream("myfile"), myhandler);
Компилятор жалуется на то, что std::ifstream("myfile")
и Handler()
являются значениями r, которые передаются как неконстантные ссылки, поэтому жалоба законна, но что я могу сделать?
- Ни один из параметров функции не может быть
const
(istream
модифицируется при чтении, а обработчик меняет свое состояние во время обратных вызовов). - Если я изменю типы параметров на ссылки rvalue (
&&
), то я не смогу передатьstd::cin
, а иногда мне действительно важно конечное состояниеmyhandler
, поэтому я не могу применить к ним иstd::move
. - В принципе, я мог бы сделать параметры универсальными ссылками с помощью шаблона или вывода типа
auto&&
и, таким образом, перегрузить эту функцию для всех возможных комбинаций ссылок lvalue и rvalue, но я не собираюсь перегружать эту функцию для других типов, кроме тех, которые я уже указал.
Есть ли другие варианты?
Как-то вся эта семантика ходов мешала в таком тривиальном примере.
std::ifstream("myfile")
— это временное значение, почему бы просто не создать для него переменную? - person πάντα ῥεῖ   schedule 16.02.2016scan
ссылки/указатели на объекты потока после его возврата? Если нет, вы можете сделатьstd::ifstream("myfile") >> std::skipws
, чтобы получить ссылку lvalue на временный файл. - person 0x499602D2   schedule 16.02.2016>>
изменяет состояние потока, и тот же трюк не применим кHandler()
. Для меня это проблема языка: внезапно я вынужден объявить некоторые временные переменные только для хранения ссылок... - person mariusm   schedule 16.02.2016&&
(т.е. позволить ему использовать оба аргумента), тогда это так. - person mariusm   schedule 16.02.2016template<class T>T& lvalue_ref(T&& x){return x;}
потом позже -scan(lvalue_ref(ifstream()), lvalue_ref(Handler()))
- person 0x499602D2   schedule 16.02.2016switch
-cases
, поэтому, если я объявляю новую переменную в этой области, компилятор жалуется, что она пересекает инициализацию. - person mariusm   schedule 16.02.2016switch
/case
, помещая их в блок области действия ({}
). - person πάντα ῥεῖ   schedule 16.02.2016lvalue_ref
кажется решением, которое я искал. Странно, что это не частьstd::
:-) - person mariusm   schedule 16.02.2016