Есть ли способ написать функцию в C++, которая принимает как аргументы lvalue, так и rvalue, не делая ее шаблоном?Функция, которая принимает как аргументы 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 не будет связываться с неконстантной ссылкой-значения.
Если я объявить его как
void print_stream(istream&& is);
то первое использование не будет компилировать, потому что именующий не будет связываться с ссылкой RValue.
Если я объявляю его как
void print_stream(const istream& is);
тогда реализация функция не будет компилироваться, так как вы не можете прочитать из const istream
.
Я не могу сделать функцию шаблоном и использовать «универсальную ссылку», потому что ее реализация должна быть отдельно скомпилирована.
Я мог бы привести две перегрузки:
void print_stream(istream& is);
void print_stream(istream&& is);
и есть второй называют первым, но это, кажется, как много ненужной шаблонного, и я бы очень жаль, придется делать это каждый раз, когда я напишите функцию с такой семантикой.
Есть ли что-то лучшее, что я могу сделать?
У вас может быть void print_stream (Wrapper) и переместить проблему в конструктор Wrapper, что имеет смысл, если вы хотите сделать то же самое для нескольких функций. –
"каждый раз, когда я пишу функцию с семантикой, подобной этой?" Часто ли вы записываете функции, которые должны принимать неконстантный аргумент без копирования, и должны быть вызваны как с временным, так и с параметром lvalue? Это довольно конкретный случай, и я не буду беспокоиться о том, «каждый раз, когда мне приходится писать функцию с семантикой, подобной этой». Если параметр был скопирован, вы можете просто передать его по значению. Если вам не нужно было называть неконстантные функции на нем, вы могли бы пройти по ссылке const – jalf
Вы могли бы написать шаблон помощника-лидера T & stay (T && t) {return t; } 'и используйте' stay (fstream {"filename"}) '. –