Is there a way to write a function in C++ that accepts both lvalue and rvalue arguments, without making it a template?
For example, suppose I write a function print_stream
that reads from an istream
and prints the data that was read to the screen, or something.
I think it's reasonable to call print_stream
like this:
fstream file{"filename"};
print_stream(file);
as well as like this:
print_stream(fstream{"filename"});
But how do I declare print_stream
so that both uses work?
If I declare it as
void print_stream(istream& is);
then the second use won't compile because an rvalue will not bind to a non-const lvalue reference.
If I declare it as
void print_stream(istream&& is);
then the first use won't compile because an lvalue will not bind to an rvalue reference.
If I declare it as
void print_stream(const istream& is);
then the function's implementation won't compile because you can't read from a const istream
.
I can't make the function a template and use a "universal reference", because its implementation needs to be separately compiled.
I could provide two overloads:
void print_stream(istream& is);
void print_stream(istream&& is);
and have the second call the first, but that seems like a lot of unnecessary boilerplate, and I would find it very unfortunate to have to do that every time I write a function with semantics like this.
Is there something better I can do?
See Question&Answers more detail:os