Есть ли способ написать функцию в С++, которая принимает как аргументы lvalue, так и rvalue, не делая ее шаблоном?
Например, предположим, что я пишу функцию print_stream
, которая читает из istream
и печатает данные, которые были прочитаны на экране, или что-то в этом роде.
Я думаю, что разумно называть print_stream
следующим образом:
fstream file{"filename"};
print_stream(file);
а также вот так:
print_stream(fstream{"filename"});
Но как объявить print_stream
так, чтобы оба использования работали?
Если я объявляю его как
void print_stream(istream& is);
то второе использование не будет скомпилировано, потому что rvalue не будет связываться с неконсольной ссылкой lvalue.
Если я объявляю его как
void print_stream(istream&& is);
то первое использование не будет компилироваться, потому что lvalue не будет привязываться к ссылке rvalue.
Если я объявляю его как
void print_stream(const istream& is);
тогда реализация функции не будет компилироваться, потому что вы не можете читать из const istream
.
Я не могу сделать функцию шаблоном и использовать "универсальную ссылку", потому что ее реализация должна быть скомпилирована отдельно.
Я мог бы предоставить две перегрузки:
void print_stream(istream& is);
void print_stream(istream&& is);
и второй вызов первый, но это похоже на много ненужного шаблона, и мне было бы очень неприятно это делать каждый раз, когда я пишу функцию с семантикой вроде этого.
Есть ли что-то лучшее, что я могу сделать?