2016-03-18 2 views
1

Следующий код компилируется в 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; 
} 

Demo

НКУ - ошибка: 'шаблон структура B' используется без параметров шаблона
лязг - ошибка: 'B' не является классом, пространства имен, или перечисление

Какой компилятор соответствует стандартным спецификациям? Любая двусмысленность в спецификациях?

Редактировать
Я добавил f() в C иметь более подходящий пример.

ответ

3

Обычно для вызова функции базового класса в этом случае можно было бы написать:

this->f(); 

Если f и g оба были статичными, вы бы, конечно, не может быть в состоянии сделать это, так что вместо того, чтобы вы могли написать

B<T>::f(); 

Это работает, потому что B уже в рамках в декларации C, поэтому компилятор уже знает, что это шаблон. Если вы делаете только B::f(), компилятор даст вам сообщение об ошибке, поскольку он знает, что B является шаблоном, поэтому предполагается наличие шаблонных аргументов.

Возможно, вам интересно, почему вам разрешено пропустить аргументы шаблона в определении B<T>, но не внутри определения C. Чтобы понять это, вам нужно знать, что каждый класс имеет имя введенного класса, которое ведет себя как typedef, объявленное в самом начале определения класса. Так что, как будто определение B началось с

typedef B<T> B; 

Использование B внутри определения B<T> найдет нагнетаемого классовое имя , а не шаблон. Но когда вы находитесь внутри C, этот B не виден, так как он объявлен внутри B<T>, который является зависимым базовым классом, а зависимые базовые классы не ищут при поиске неквалифицированного имени (а B находится слева от ::, поэтому поиск B является неквалифицированным).Это также работает:

C::B::f(); 

В этом случае вводится класс имя C найдено, и это относится к зависимому типу C<T>, поэтому поиск в B будет искать внутри зависимого базового класса B<T> и найдите нужный имя введенного класса.

1

Проблема в struct C, функция f от B вызывается без параметра шаблона.

0

Компилятор не знает B Вы имеете в виду в B::f();, попробуйте изменить его на B<T>::f();.

+0

Правильно, я знаю, что B :: f() работает. Разрабатывая код кросс-платформы, раздражает то, что некоторый код компилируется с одним компилятором, а не с другими. Я хотел бы знать, что говорит о стандарте, и если три компилятора могут быть выровнены, чтобы дать тот же результат компиляции (успешный или нет) ... –

Смежные вопросы