作者sarafciel (Cattuz)
看板C_and_CPP
標題Re: [問題] 泛型出現ERROR但編譯可過,可執行
時間Mon May 13 13:39:54 2019
※ 引述《s4300026 (s4300026)》之銘言:
: 標題: [問題] 泛型出現ERROR但編譯可過,可執行
: 時間: Fri May 10 18:41:31 2019
:
: 開發平台(Platform): (Ex: Win10, Linux, ...)
: win10
:
: 編譯器(Ex: GCC, clang, VC++...)+目標環境(跟開發平台不同的話需列出)
: VC++
:
: 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
: #include <string>
:
: 問題(Question):
: 泛型函式可以編譯和執行
:
: 但是撰寫VC程式碼時會出現紅字底線 (ERROR), 表示方法未定義
:
: 餵入的資料(Input):
: N/A
:
: 預期的正確結果(Expected Output):
: 是正確的
:
: 錯誤結果(Wrong Output):
: 紅字看起來很礙眼
:
: 程式碼(Code):(請善用置底文網頁, 記得排版,禁止使用圖檔)
: https://ideone.com/6JheE0
:
: 補充說明(Supplement):
:
: 1. VC照片如下
: https://imgur.com/a/7gjzbLY
:
: 2. 當Source.cpp不存在時,不會出現錯誤,
:
: 但我不是很想只因為這個原因而獨立成一個專案。
:
: --
: ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 60.250.235.221
: ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1557484894.A.E01.html
: ※ 編輯: s4300026 (60.250.235.221), 05/10/2019 18:42:12
: → sarafciel: 把GetSubwstring前的Trans::去掉 05/10 21:28
: 回樓上,今天一早就來試,還真的沒有了!
:
: 能請教一下為什麼嗎? 我的意思:是方法前面,
:
: 我記得本來就是可加可不加類別名吧?
:
雙冒號(::)是用來描述scope的,並不是可加可不加,有些場合一定要加
舉個例子
https://ideone.com/PSm7pe
C++允許你在類別外跟類別內定義介面跟名稱完全一樣的函式
而這個時候你寫bar(),編譯器只會看global scope找有沒有定義可以呼叫的bar
只有加了foo::告訴編譯器你要的bar是在
「class foo的scope裡」
才能call到裡面的那個版本
: 至少在非泛型使用上都沒問題...
:
: 原本我想要在.cpp上撰寫泛型方法
:
延續上面的例子 這時候我把函式內的定義拿掉 只留宣告
然後把定義寫在函式外,但是不加foo::的scope描述:
https://ideone.com/kTLuCC
編譯器報undefined reference,因為他以為你要定義的是global scope的bar函式
所以你類別外定義時必須寫成foo::bar,讓編譯器知道你是在定義class foo下的函式
: 後來怎麼寫都過不了,最後只能把他貼回.h撰寫
:
: 方法前面的類別名是那時候遺留下來的
: ※ 編輯: s4300026 (114.137.115.219), 05/13/2019 08:44:00
對,你為了在類別外定義時能編譯過,所以寫在外面時有把scope::加上去
然後因為template不給過的緣故,你把定義搬回去class內了
而在class內編譯器自然很清楚你在寫的是該class scope的函式
所這個時候是不用加foo::去指定scope的(當然有些例外,比方說菱形繼承)
至於template為什麼過不了,因為template是編譯時再去生成相對應的c++ code
你沒有用到它就不會生,這是為什麼你沒有souce.cpp他不會報錯的原因
反過來說,因為他是用到時才去生成,所以生程式碼時你的模板定義一定要是完整的
如果你把模板定義寫在某個A.cpp裡,然後在B.cpp要使用在A.hpp宣告的模板
這時候因為B.cpp只能看到A.hpp的模板宣告
位於A.cpp的模板定義他沒有看到,自然沒辦法生
所以模板一般會直接在header裡把定義寫完
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 210.242.163.170
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1557726002.A.2C7.html
推 ilikekotomi: 上了一課 感謝分享 05/13 20:04
推 s4300026: 感謝~ 我已經明白為什麼我的模板不能放在cpp的原因了! 05/15 08:35
推 s4300026: 但是我對於scope::還是有不了解的地方,我想詢問在.h檔 05/15 08:37
→ s4300026: class範圍內宣告的方法,所謂的不用加scope::是指不能加 05/15 08:39
→ s4300026: 還是加不加都可以? 因為在宣告普通方法的時候,scope:: 05/15 08:40
→ s4300026: 似乎是不影響VC的編譯的(都可以編譯且無warning) 05/15 08:41
→ s4300026: 05/15 08:51
→ s4300026: 我是明白.cpp加不加的差異 我也知道發生宣告 Ambiguous 05/15 08:52
→ s4300026: 時要加,但我不知道當宣告沒發生 Ambiguous 時的情況 05/15 08:54
→ s4300026: 因為有時候在寫定義時會想到更好的宣告名稱,就直接 05/15 09:01
→ s4300026: 或者是更改輸出入,把定義處的標題直接複製到宣告式中 05/15 09:03
應該是VS2015還容許這種寫法吧
就我自己在VS2017上面試,這種寫法是會報錯的
早期的gcc也可以寫這種style的宣告,現在基本上都會跳error了
另外VS是有支援全專案重新命名的,請好好利用IDE的功能XD
※ 編輯: sarafciel (123.193.54.11), 05/15/2019 19:42:04
推 s4300026: 好窩,感謝XD 05/16 08:19