[英]Calling virtual method of base template from derived variadic template class
[英]Calling method of template base class
以下代碼在visual studio 2015中編譯(即使使用/ Za選項)。 它不能在gcc和clang上編譯。
struct A
{
};
template<typename T>
struct B
{
void f()
{
}
};
template<typename T>
struct C : B<T>
{
void f()
{
}
void g()
{
B::f();
}
};
int main()
{
C<A> c;
c.g();
return 0;
}
gcc - 錯誤:'模板結構B'在沒有模板參數的情況下使用
clang - 錯誤:'B'不是類,命名空間或枚舉
哪種編譯器符合標准規范? 規格中有任何歧義嗎?
編輯
我在C
添加了f()
以得到一個更相關的例子。
通常在這種情況下調用基類函數,你會寫:
this->f();
如果f
和g
都是靜態的,你當然不能這樣做,所以你可以寫
B<T>::f();
這是有效的,因為B
已經在C
的聲明范圍內,因此編譯器已經知道它是一個模板。 如果單獨執行B::f()
,編譯器會給你一個錯誤,因為它知道B
是一個模板,所以它應該有模板參數。
您可能想知道為什么允許在B<T>
的定義中省略模板參數,但不允許在C
的定義中省略。 要理解這一點,您需要知道每個類都有一個注入類名 ,其行為類似於在類定義的最開始聲明的typedef。 所以就好像B
的定義一樣
typedef B<T> B;
在B<T>
的定義中使用B
將找到注入的類名 ,而不是模板。 但是當你在C
里面時,這個B
是不可見的,因為它是在B<T>
聲明的,它是一個依賴的基類,並且在非限定名稱查找期間不搜索依賴的基類范圍(並且B
在左邊::
,所以B
的查找是不合格的)。 這也有效:
C::B::f();
在這種情況下,找到注入類名 C
,它引用依賴類型C<T>
,因此B
的查找將在依賴基類B<T>
內搜索並找到所需的注入類 -名字 。
問題出在struct C
,在沒有模板參數的情況下調用B
的函數f
。
編譯器不知道B
你指的是在B::f();
,嘗試將其更改為B<T>::f();
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.