記錄一次比較無語的語法錯誤 - "error: ‘ostream’ has not been declared"


  記錄一個讓筆者有點無語的語法錯誤 debug 過程...

 

  1.晚上使用 VScode 寫代碼,編譯時出現如下報錯信息 "error: ‘ostream’ has not been declared".編譯無法通過.

    error: ‘ostream’ has not been declared        // ostream 未聲明

  2.產生上述報錯時,源文件中包含了頭文件 iostream.筆者第一反應,是和 C 語言下出現類似報錯時一樣,認為可能沒有包含對應聲明了 ostream 類型的頭文件.比如 C 語言中,如果沒有包含頭文件 stdio.h,則在源文件中使用 printf 同樣會產生 'printf' has not been declared 的報錯.所以筆者懷疑頭文件 iostream 中沒有包含對 ostream 的聲明( 雖然這個懷疑筆者也覺得有點奇怪... ).

  3.使用 VScode 進行代碼編輯時,可以通過選中某個頭文件,右鍵 -> 轉至定義( go to definition )/查看定義( peek definition ) 查看頭文件的內容.所以筆者直接就想看看頭文件 iostream 中是否包含所想要的 ostream 聲明.於是進入頭文件 iostream,發現該頭文件開始位置包含了頭文件 ostream...內心 os : 這個頭文件 ostream 怎么看也應該包含有類型 ostream 的聲明啊...要不為啥叫這名...

  4.覺得頭文件 ostream 中應該包含有 ostream 的類型聲明,所以包含頭文件 iostream => 包含頭文件 ostream => 包含有 ostream 類型聲明,那么使用 ostream 應該是可以的.所以再編譯一次程序.結果繼續,"error: ‘ostream’ has not been declared".有點抓狂.

  5.於是懷疑,難道頭文件 ostream 中都不包含有 ostream 的類型聲明???所以首先,打開了 ostream 的內容,發現其中主要定義的是一個叫做 basic_ostream 的類模版,直接搜索 ostream 關鍵詞不好定位 ostream.於是一怒之下,打開了 cplusplus-ostream ,查看頭文件 ostream 的介紹,發現其中確實是有類 ostream 的.

  

  繼續進入查看類 ostream 的說明( class std::ostream ),發現 ostream 的定義如下,所以直接在頭文件 ostream 中搜索該定義,結果查找不到...內心 os : 這是個什么鬼...頁面上說有,頭文件里面沒有?

    typedef basic_ostream<char> ostream;        // ostream 的定義

  6. ostream 的聲明到底在哪里?筆者覺得不能放棄.於是想到,輸出流 cout 就是 ostream 類型的,其在頭文件 iostream 中有聲明如下,其中用到了類型 ostream.

    extern ostream cout;        //頭文件 iostream 中對 cout 的聲明

  直接選中 ostream,然后右鍵 -> 轉到定義,跳轉到 ostream 的定義,發現其位於頭文件 iosfwd 中,且形式與前面頁面介紹的 ostream 定義相同.根據頭文件 isofwd 的介紹,該頭文件包含的是一些與 io 有關的前向聲明.

  

  此時筆者心中對於 ostream 出現的位置還是有點詫異,為啥會出現在這里呢?這跟 cplusplus 網站上介紹的不太一樣啊...同時,筆者在/查看頭文件定義的過程中如 iostream 時,發現 VScode 會報告系統上存在兩個對應頭文件,比如筆者 Ubuntu 環境下,系統頭文件位置在 /usr/include/c++/ 目錄下,而其中包含有 5.5.0/7.5.0 的頭文件版本.此時筆者甚至開始懷疑,難道是因為頭文件版本的改變使得 ostream 定義的位置發生了改變?腦洞逐漸變大...

  7.既然找到了 ostream 的聲明,那么筆者最直接的思路,就是在源文件中直接包含頭文件 iosfwd,再進行編譯.結果仍然"error: ‘ostream’ has not been declared".這就很讓人郁悶了???到底是因為啥?

  8.於是筆者最后,做了一個本來之前就應該做的事情--google.輸入關鍵詞 error: ‘ostream’ has not been declared.返回的搜索條目中第一條是 stackoverflow 的一個問題 istream and ostream problem - C++,其第一個答案說,請確保在使用 ostream 前加入對應的命名空間的聲明.........然后筆者就聽話的在源文件中加入了命名空間聲明,然后就編譯通過了..........

    using std::ostream;        //聲明

  9.那么為什么只需要包含頭文件 iostream 就包含了對類型 ostream 的聲明呢,而且貌似 ostream 文件中還不含有 ostream 的聲明?其實原因是,頭文件 iostream 包含了頭文件 ostream => 頭文件 ostream 包含了頭文件 ios => 頭文件 ios 包含了頭文件 iosfwd => 頭文件 iosfwd 就包含了 ostream 的聲明...所以就齊活了...istream 的情況與 ostream 類似.

  

  emmmmm,所以說,有時候遇到這種編譯問題,思路是需要活躍一點,但有時候, google 一下可能就直接解決了...

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM