Reputation: 979
The compiler does not like the the main program below
int get1(ifstream &f){
int count;
f >> count;
return count;
}
int main(int argc, char** argv){
cout << get1(ifstream(argv[1])) << endl;
}
The error message is:
test.cpp: In function 'int main(int, char**)':
test.cpp:11:33: error: invalid initialization of non-const reference of type 's\
td::ifstream& {aka std::basic_ifstream<char>&}' from an rvalue of type 'std::if\
stream {aka std::basic_ifstream<char>}'
test.cpp:4:5: error: in passing argument 1 of 'int get1(std::ifstream&)'
This does work if the main program is written as
int main(int argc, char** argv){
ifstream f(argv[1]);
cout << get1(f) << endl;
}
Is there a way to make the compact first form work?
Upvotes: 3
Views: 1708
Reputation: 15069
get1(ifstream(argv[1]))
You are constructing a temporary ifstream
object. Temporary objects can only be bound to const references (const ifstream&
), not to non-const references (ifstream&
).
Is there a way to make the compact first form work?
It depends on which version of C++ you're using.
In C++11 you can change your function to use a rvalue reference instead of a lvalue reference: int get1(ifstream&& f)
. Then it will gladly accept temporary objects. (solution courtesy of @soon)
Note however that with this solution, if you want to use the less compact form ifstream f(argv[1]); get1(f);
the compiler won't accept it as is (cannot bind ‘T’ lvalue to ‘T&&’
). You'll have to use std::move
in order to convert the lvalue to a rvalue: get1(std::move(f));
.
Another way, which avoids the std::move
requirement, would be to use a template function with an universal reference (special case of rvalue references for templates, that allows the rvalue reference to decay to a lvalue reference): template<Stream> int get1(Stream&& f)
(courtesy @soon once again)
In C++03 there is no standard way to do it: since temporary objects can only be bound to const references, you'd have to change your function to int get1(const ifstream& f)
which would render your ifstream
useless (who'd want an ifstream
that can't be read because it is const
?).
Upvotes: 9