Полученный доступ к шаблону classа к элементам-членам базового classа

Этот вопрос является продолжением вопроса, заданного в этой теме .

Используя следующие определения classов:

template  class Foo { public: Foo (const foo_arg_t foo_arg) : _foo_arg(foo_arg) { /* do something for foo */ } T Foo_T; // either a TypeA or a TypeB - TBD foo_arg_t _foo_arg; }; template  class Bar : public Foo { public: Bar (const foo_arg_t bar_arg, const a_arg_t a_arg) : Foo(bar_arg) // base-class initializer { Foo::Foo_T = T(a_arg); } Bar (const foo_arg_t bar_arg, const b_arg_t b_arg) : Foo(bar_arg) { Foo::Foo_T = T(b_arg); } void BarFunc (); }; template  void Bar::BarFunc () { std::cout << _foo_arg << std::endl; // This doesn't work - compiler error is: error: '_foo_arg' was not declared in this scope std::cout << Bar::_foo_arg << std::endl; // This works! } 

При доступе к членам базового classа classа шаблона кажется, что я всегда должен явно квалифицировать членов, используя синтаксис шаблона в стиле Bar::_foo_arg . Есть ли способ избежать этого? Может ли «использование» инструкции / директивы вступить в игру в методе classа шаблона для упрощения кода?

Редактировать:

Проблема области разрешена путем определения переменной с помощью этого синтаксиса.

3 Solutions collect form web for “Полученный доступ к шаблону classа к элементам-членам базового classа”

Вы можете использовать this-> чтобы четко указать, что вы имеете в виду члена classа:

 void Bar::BarFunc () { std::cout < < this->_foo_arg < < std::endl; } 

В качестве альтернативы вы также можете использовать « using » в методе:

 void Bar::BarFunc () { using Bar::_foo_arg; // Might not work in g++, IIRC std::cout < < _foo_arg << std::endl; } 

Это дает понять компилятору, что имя члена зависит от параметров шаблона, чтобы оно искало определение этого имени в правильных местах. Для получения дополнительной информации см. Эту запись в C ++ Faq Lite .

Здесь базовый class не является независимым базовым classом (который означает один с полным типом, который может быть определен без знания аргументов шаблона), а _foo_arg – это независимое имя. В стандартном C ++ говорится, что независимые имена не просматриваются в зависимых базовых classах.

Чтобы исправить код, достаточно _foo_arg имя _foo_arg зависимым, потому что зависимые имена могут быть просмотрены только во время создания экземпляра, и в то время будет известна точная базовая специализация, которая должна быть исследована. Например:

 // solution#1 std::cout < < this->_foo_arg < < std::endl; 

Альтернативой является введение зависимости с использованием квалифицированного имени:

 // solution#2 std::cout < < Foo::_foo_arg < < std::endl; 

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

И вы можете принести имя из зависимого базового classа в производном classе один раз, using :

 // solution#3 template  class Bar : public Foo { public: ... void BarFunc (); private: using Foo::_foo_arg; }; template  void Bar::BarFunc () { std::cout < < _foo_arg << std::endl; // works } 

Появляется, чтобы отлично работать в Visual C ++ 2008. Я добавил некоторые фиктивные определения для типов, о которых вы упомянули, но не предоставил источник. Остальное точно так же, как вы выразились. Затем основная функция для принудительного создания и BarFunc .

 #include  class streamable {}; std::ostream &operator< <(std::ostream &os, streamable &s) { return os; } class foo_arg_t : public streamable {}; class a_arg_t : public streamable {}; class b_arg_t : public streamable {}; template  class Foo { public: Foo (const foo_arg_t foo_arg) : _foo_arg(foo_arg) { /* do something for foo */ } T Foo_T; // either a TypeA or a TypeB - TBD foo_arg_t _foo_arg; }; template  class Bar : public Foo { public: Bar (const foo_arg_t bar_arg, const a_arg_t a_arg) : Foo(bar_arg) // base-class initializer { Foo::Foo_T = T(a_arg); } Bar (const foo_arg_t bar_arg, const b_arg_t b_arg) : Foo(bar_arg) { Foo::Foo_T = T(b_arg); } void BarFunc (); }; template  void Bar::BarFunc () { std::cout < < _foo_arg << std::endl; std::cout << Bar::_foo_arg < < std::endl; } int main() { Bar *b = new Bar(foo_arg_t(), a_arg_t()); b->BarFunc(); } 
  • Почему мне приходится обращаться к членам базового classа шаблонов через этот указатель?
  • Можно ли создавать стандартные шаблоны контейнеров с неполными типами?
  • Проверьте, имеет ли class функцию-член определенной подписи
  • Изменение шаблонов в Xcode
  • Обходное решение для вывода аргумента шаблона в невыводимом контексте
  • Проблема с шаблоном вызывает ошибку компоновщика (C ++)
  • Когда использовать std :: forward для пересылки аргументов?
  • Что такое «непосредственный контекст», упомянутый в стандарте C ++ 11, для которого применяется SFINAE?
  • Почему шаблон функции не может быть частично специализированным?
  • Можете ли вы рекомендовать механизм шаблонов .net?
  • Проблема GCC: использование члена базового classа, который зависит от аргумента шаблона
  • Давайте будем гением компьютера.