[英]Why do two functions have the same address?
考慮這個功能模板:
template<typename T>
unsigned long f(void *) { return 0;}
現在,我將f<A>
和f<B>
的地址打印為:
std::cout << (void*)f<A> << std::endl;
std::cout << (void*)f<B> << std::endl;
如果在MSVS10中編譯,為什么它們會打印相同的地址? 它們不是兩個不同的功能,因此應該打印不同的地址嗎?
更新:
我意識到在ideone上,它會打印出不同的地址。 MSVS10優化代碼,因為函數不以任何方式依賴於T
,因此它產生相同的功能。 @Mark的回答和對此的評論很有價值。 :-)
你需要施放到void *
:
std::cout << (void*)(ftype*)f<A> << std::endl;
std::cout << (void*)(ftype*)f<B> << std::endl;
如果轉換為函數指針(或其他幾類非void指針),它將被operator<<
for std::ostream
(因此為1
)解釋為bool
。
由於該函數不依賴於模板參數,因此編譯器可以將所有實例化壓縮為單個函數。
我不知道你為什么得到1
的地址。
我試驗了我的真實代碼,並得出結論,@Mark上面說的內容非常重要:
由於該函數不依賴於模板參數,因此編譯器可以將所有實例化壓縮為單個函數。
我還得出結論,如果函數體依賴於T*
而不是T
,它仍然會為我的實際代碼中的不同類型參數生成相同的函數(不過在ideone上)。 但是,如果它依賴於T
,那么它會產生不同的函數,因為sizeof(T)
)對於不同的類型參數有所不同(幸運的是我)。
所以我在函數模板中添加了一個類型為T
的虛擬自動變量,這樣函數就可以依賴於T
的大小來強制它產生不同的函數。
這只是一個未定義行為的情況,因為將指向函數的指針轉換為指向對象類型的指針的結果是未定義的。
要檢查的更有趣的表達式是f<A> == f<B>
,當且僅當A
和B
引用相同類型時,才應評估為true
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.