2013-05-18 44 views
3

下面爲什麼我不能通過ifstream構建它?

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; 
} 

有一種使緊湊的第一種形式工作的方法?

回答

9
get1(ifstream(argv[1])) 

您要構建臨時ifstream對象。臨時對象只能綁定到常量引用(const ifstream&),而不能綁定到非常量引用(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有做它沒有標準的方法:因爲臨時對象只能綁定到常量重您必須將您的功能更改爲int get1(const ifstream& f),否則ifstream將無法​​使用(誰希望ifstream無法讀取,因爲它是const?)。

+0

儘管我很不情願提及它,但因爲它絕對很糟糕,所以有一種方法:MSVC的惡意擴展。 – chris

+1

@chris是的,我猶豫了一提,但最後決定不要:叫我迂腐,但這不是C++了。 – syam

+2

我不確定,但沒有通過r-reference解決方案? – soon

相關問題