С++ вызов шаблонных функций базового класса

Ниже приведены два случая.

Случай 1) Base->BaseIndirect->DerivedIndirect

Случай 2) База->Производная

В случае 2) я могу вызвать функцию шаблона базового класса, используя 3 нотации. В случае 1) я могу вызвать функцию шаблона базового класса, используя только одну из этих нотаций. И я НЕ могу вызвать функцию шаблона BaseIndirect, используя любую нотацию :(. Как мне это исправить? Спасибо.

struct Base {
  template<bool R> inline void fbase(int k) {};
};

template<class ZZ> struct BaseIndirect : Base {
  template<bool R> inline void fbaseIndirect(int k) {};
};


template<class ZZ>
struct DerivedIndirect : BaseIndirect<ZZ> {
  DerivedIndirect() {
    this->fbase<true>(5);         // gives error, line 13
    fbase<true>(5);               // gives error, line 14
    Base::fbase<true>(5);           // WORKS, line 15
    this->fbaseIndirect<true>(5); // gives error, line 16
    fbaseIndirect<true>(5);       // gives error, line 17
    BaseIndirect<ZZ>::fbaseIndirect<true>(5);   // gives error, line 18
  }
};

template<class ZZ>
struct Derived : Base {
  Derived() {
    this->fbase<true>(5); //  WORKS
    fbase<true>(5);       // WORKS
    Base::fbase<true>(5); // WORKS
  }
};


int main() {
  Derived<int> der;
  DerivedIndirect<int> derIndirect;
};                              

ОШИБКИ при компиляции

test.cpp: In constructor 'DerivedIndirect<ZZ>::DerivedIndirect()':
test.cpp:14: error: 'fbase' was not declared in this scope
test.cpp:17: error: 'fbaseIndirect' was not declared in this scope
test.cpp: In constructor 'DerivedIndirect<ZZ>::DerivedIndirect() [with ZZ = int]':
test.cpp:34:   instantiated from herep 
test.cpp:13: error: invalid operands of types '<unresolved overloaded function type>' and 'bool' to binary 'operator<'
test.cpp:16: error: invalid operands of types '<unresolved overloaded function type>' and 'bool' to binary 'operator<'
test.cpp:18: error: invalid operands of types '<unresolved overloaded function type>' and 'bool' to binary 'operator<'

person anon    schedule 08.02.2011    source источник
comment
Пробовали ли вы добавлять операторы using Some_Base::identifier в производные классы?   -  person Tony Delroy    schedule 08.02.2011


Ответы (1)


Причина, по которой многие из этих вызовов терпят неудачу, заключается в том, что существует синтаксическая двусмысленность, которую необходимо устранить с помощью единственного наиболее непонятного использования ключевого слова template. Вместо того, чтобы писать

this->fbase<true>(5);

Вам нужно написать

this->template fbase<true>(5);

Причина в том, что без ключевого слова template компилятор анализирует это как

(((this->fbase) < true) > 5)

Что неразумно. Ключевое слово template явно устраняет эту двусмысленность. Добавление ключевого слова template в другие упомянутые вами случаи должно решить эти проблемы.

На самом деле я не уверен, почему это работает для прямых базовых классов, поэтому, если бы кто-то мог ответить на эту часть вопроса, я бы хотел узнать, каков ответ.

person templatetypedef    schedule 08.02.2011
comment
Это не работает для прямых базовых классов; единственный случай, когда это сработало, — это явное использование нешаблонного имени базового класса Base. - person Jeremiah Willcock; 08.02.2011
comment
Ничего себе, это действительно самое непонятное использование ключевого слова шаблона, ха-ха! Спасибо, это избавило меня от некоторых проблем! - person B M; 19.02.2014