簡體   English   中英

g ++未報告未實例化模板中的某些錯誤

[英]Certain errors in uninstantiated template not reported by g++

考慮以下示例:

class A
{
  void foo();
  public:
  void bar();
};

template <class> class B
{
  B()
  {
    A a;
    a.foo();    // 1
    A::bar();   // 2
    a.bar(1);   // 3
  }
};

注意B從未實例化。

clang++報告所有三個標記的行都是錯誤的。 g++ (4.8.3)接受第1行和第2 ,僅報告第3行。

如果實例化了B ,則g++高興地將所有三行報告為錯誤。

這是g++錯誤嗎? 有人會這樣想。 A不是從屬名稱,應在模板定義時正常檢查其成員。 有沒有我看不到的細微差別?

這些預實例化消息不是由標准強制執行的,而是由編譯器決定的

n3337§14.6-8

不得針對可為其生成有效專業化的模板定義發布診斷。 如果無法為模板定義生成有效的專業化名稱,並且未實例化該模板,則該模板定義格式錯誤, 無需診斷。

重點礦

通常無法判斷a.foo();是否a.foo(); A::bar(); 在模板定義時是一個錯誤,即使對於A::fooA::bar那些特定定義也是如此。

一般來說, a.foo(); 如果A作為朋友有B<T>某些特化,而沒有其他特化,則可能是有效的,這會使有效性取決於模板參數。

一般來說, A::bar(); 如果B<T>直接或間接將A作為基類,並且模板類通常在模板定義時尚不知道其基類,則可能有效。

即使可以在此處檢測到這兩種方法都不可行( A沒有朋友,而B<T>沒有鹼),也需要付出很大的努力才能獲得很少的收益。 因此,僅在實例化時簡單地執行此類檢查就很有意義,這就是GCC采取的方法。

實際上,在C ++中沒有規則要求在模板定義時對此進行診斷(正如Marco A.的答案正確指出的那樣)。 僅當實例化模板時,模板定義中的任何錯誤才會使程序按照2.2p1項目符號要點8的形式出現格式錯誤,並需要進行診斷:

如果任何實例化失敗,則程序的格式不正確。

在您的程序中,沒有實例化,因此沒有失敗的實例化。

暫無
暫無

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

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