[英]Is an implementation required to diagnose ODR-violations of duplicated definitions of the same explicit specialization within the same TU?
考慮一個模板化實體,例如 (A) 一個 function 模板,和 (B) 一個 class 模板的成員枚舉。
// (A)
template<auto>
int f();
// (B)
template <auto>
struct T { enum class E; };
由於此類模板實體的相同顯式專業化的重復定義,是否需要實施來診斷 ODR 違規? 或者,換句話說, [basic.def.odr]/1是否適用於明確的專業化?
例如 GCC 和 Clang 都將以下程序診斷為格式錯誤:
// Single translation unit;
// primary template of 'f' declared as in (A) above.
template<>
int f<0>() { return 0; }
template<>
int f<0>() { return 1; }
// GCC & Clang - error: redefinition of 'int f() [with auto <anonymous> = 0]'
而只有 Clang 將后續程序診斷為格式錯誤,而 GCC 接受它:
// Single translation unit;
// primary template of 'T' defined as in (B) above.
template<>
enum class T<0>::E { ex };
template<>
enum class T<0>::E { ey };
// Clang only - error: redefinition of 'E'
格式錯誤的 NDR,還是格式錯誤? (/兩個編譯器都正確,還是 GCC 錯誤?)
在各種 GCC 和 Clang 版本上測試,對於-std=c++17
和-std=c++2a
,結果相同
由於此類模板實體的相同顯式專業化的重復定義,是否需要實施來診斷 ODR 違規?
是的。
盡管[temp.spec]/5.2指定程序中顯式專業化的多個定義格式錯誤(同時引用 [basic.def.odr])NDR(不需要診斷),但單個 TU 中的多個定義屬於[basic.def.odr]/1 ,例如 class 模板的顯式特化(對於某些設置的模板參數)是 class。
任何翻譯單元都不得包含多個變量的定義,function、class 類型、枚舉類型或模板。
違反 [basic.def.odr]/1 不是 NDR,實現應對其進行診斷,GCC 和 Clang 對違反 ODR 的顯式專業化(在同一 TU 內)這樣做:
但是,對於 class 模板的成員枚舉的明確專業化,只有 Clang 將其診斷為 TU 本地 ODR 違規,這是問題中使用的非常示例。
因此,這個成員枚舉的未診斷案例是 GCC 錯誤(作為此問題的一部分提交):
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.