2015-10-17 52 views
15

我正在嘗試使用ifstream打開文件失敗的測試程序。代碼如下: -C++ Ifstream對象等於nullptr,但它不是一個指針?

#include <iostream> 
#include <fstream> 
#include <type_traits> 
using namespace std; 
int main() 
{ 
    ifstream ifs ("wrong_filename.txt"); 
    cout << boolalpha; 
    cout << is_pointer<decltype(ifs)>::value <<"\n"; 
    cout << (ifs==nullptr); 
    return 0; 
} 

輸出是: -

false 
true 

如果ifs不是pointer,那麼如何它等於nullptr

+0

'void *'IIRC有一個強制重載。 –

+0

任何類類型都可以通過定義隱式轉換爲指針類型或通過適當地重載'operator =='來選擇與'nullptr'相媲美。 –

+2

詢問「疑問」時爲編譯器命名。 –

回答

22

直到C++ 11,C++流可以隱式轉換爲void*。如果流不處於無錯狀態,則返回NULL,否則返回其他值。因此,ifs == NULL(不應與nullptr一起使用,請參閱下文)將會找到並使用該轉換,並且由於您的文件名是錯誤的,所以比較結果將爲真。

在C++ 11,將其改變成顯式轉換到bool,與false指示錯誤和true良好的流,這是因爲void*轉換允許太多無意義的代碼,如你的例子。事實上,當前在C++ 11或C++ 14模式下的編譯器會拒絕您的代碼段live。由於您的代碼顯然至少是C++ 11,因此您的編譯器通過接受它而不符合規範。

這些轉換允許的,旨在用於錯誤檢查這樣的:

if (!(ifs >> data)) 
    std::cout << "Reading data failed."; 

,或者類似的例子:

std::ifstream ifs ("wrong_filename.txt"); 
if (!ifs) 
    std::cout << "Could not open file."; 

一天的趣事:您還可以使用這乾淨地循環一個文件,例如:

for (std::string line; std::getline(ifs, line);) { 
    // Process line 
} 
+0

嘿! cout <<(ifs == false)也會拋出錯誤 – CppNITR

+0

@CppNITR您需要*布爾上下文*,這是觸發顯式布爾轉換的上下文。例如,轉換爲「布爾」,「if」條件或「for」標題的第二部分。 – Quentin

+0

@CppNITR因爲'bool'轉換是'顯式的'。很好的結果,更新了答案,謝謝。 –

相關問題