簡體   English   中英

模板專業化,在Windows vs GCC上的不同行為?

[英]template specialization, different behavior on windows vs gcc?

我正在尋找有關GCC與MSVC在專門化模板類的編譯+鏈接方面的不同之處的概述或說明。 例如,這種類型的東西在GCC上有效,但不適用於MSVC:

// Base.h
template <typename T> struct Base {
    template <class G>  QString  makeTitle(const G* obj){obj->CompilerError();}
    };

// in Foo.cpp
template <> template <class G> QString Base<T_1>::makeTitle(const G* obj) {  return mystr(); }
void SomeFunc() {
  std::cout<<  Base<T_1>().makeTitle<myclass>() ;
}

解決方案往往是在使用它之前,我必須在Base.h中聲明特殊化,否則在Windows上會出現鏈接錯誤。 MSVC如何/為何隱式地實例化不同,以及為什么/為什么GCC對某些cpp文件中聲明的專業化具有魯棒性?

有關一般“使用前聲明”要求的相關問題: 模板專門化-MSVC與GCC / MinGW之間的行為不同

第一件事是,如果任何翻譯單元包括標頭並導致專業化定義而編譯器看不到聲明,則您的代碼違反了ODR規則。 由於這是未定義的行為,因此一個編譯器接受它而另一編譯器拒絕它的事實完全在合理范圍之內。

正如您已經知道的那樣,正確的代碼是提供專業化的聲明,並且可以在任何編譯器中使用。

至於為什么它似乎可以工作,或者甚至為什么它實際上可以在gcc中工作,這很可能與代碼的生成方式以及鏈接程序處理目標文件有關。 特別是在gcc中,編譯器將在需要它的翻譯單元中生成專業化(並且看不到您自己的專業化),但是會將其標記為符號。 如果除(最多)一個定義之外的所有定義都是弱的,則gcc鏈接器將接受被多重定義的符號,而將強符號保留在最終的可執行文件中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM