Microsoft Visual C 中的兩階段範本實例化:問題是什麼?
Microsoft Visual C (MSVC) 因其所謂的兩階段範本實例化的錯誤實現。此方法由 C 標準定義,由兩個不同的階段組成:
第一階段:
第二階段:
MSVC 的缺陷:
MSVC 的主要問題在於它無法對非依賴表達式執行早期(第一階段)查找。相反,它將所有查找推遲到第二階段,從而導致不正確的行為。此外,MSVC 的第二階段未正確遵循非 ADL 查找規範,在此階段不應擴展該規範。
範例:
考慮以下程式碼:
int foo(void*); template<typename T> struct S { S() { int i = foo(0); } }; void foo(int); int main() { S<int> s; }
符合標準的編譯器應該將'foo(0)' 呼叫綁定到第一階段期間的「foo(void*)」。然而,MSVC 在第二階段錯誤地將其綁定到 'foo(int)',導致初始化期間出錯。
額外的不正確層:
即使在初始化期間第二階段,MSVC未能遵守標準中不應該擴展非ADL查找的規定。這會導致包含第一階段不可用的聲明,從而導致意外行為。
例:
namespace N { struct S {}; } void bar(void *) {} template <typename T> void foo(T *t) { bar(t); } void bar(N::S *s) {} int main() { N::S s; foo(&s); }
此處,'bar(t )' 應該解析為'void bar(void )',儘管在第二階段得到了解決。然而,MSVC 錯誤地將其解析為“void bar(N::S s)”,這表明其實作是錯誤的。
結論:
MSVC 的兩個-階段模板實例化實現未能完全遵守C 標準,導致在處理非依賴表達式和非ADL 查找時出現不正確的行為。這些缺陷可能會導致意外的編譯時錯誤和程式行為。
以上是為什麼MSVC的兩階段模板實例化偏離C標準?的詳細內容。更多資訊請關注PHP中文網其他相關文章!