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