编译器不喜欢下面的主程序
int get1(ifstream &f){
int count;
f >> count;
return count;
}
int main(int argc, char** argv){
cout << get1(ifstream(argv[1])) << endl;
}
Run Code Online (Sandbox Code Playgroud)
错误消息是:
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&)'
Run Code Online (Sandbox Code Playgroud)
如果主程序被写为,这确实有效
int main(int argc, char** argv){
ifstream f(argv[1]);
cout << get1(f) << endl;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法使紧凑的第一种形式工作?
get1(ifstream(argv[1]))
Run Code Online (Sandbox Code Playgroud)
您正在构建一个临时 ifstream对象.临时对象只能绑定到const引用(const ifstream&),而不能绑定到非const引用(ifstream&).
有没有办法使紧凑的第一种形式工作?
这取决于您使用的C++版本.
在C++ 11中,您可以将函数更改为使用右值引用而不是左值引用:int get1(ifstream&& f).然后它会很乐意接受临时物品.(解决方案由@soon提供)
但请注意,使用此解决方案时,如果要使用不太紧凑的表单ifstream f(argv[1]); get1(f);,编译器将不会接受它(cannot bind ‘T’ lvalue to ‘T&&’).你必须使用std::move才能将左值转换为右值:get1(std::move(f));.
另一种方式,它避免了std::move要求,将使用与模板功能的通用参考(特殊情况下,右值的参考模板,允许右值的参考衰变左值参考): template<Stream> int get1(Stream&& f)(礼貌@soon再次)
在C++ 03中没有标准的方法可以做到这一点:因为临时对象只能绑定到const引用,你必须改变你的函数,int get1(const ifstream& f)这会使你的ifstream无用(谁想要一个ifstream不能用的)阅读,因为它是const?).