Я хотел бы реализовать статический полиморфизм, используя CRTP а также добавьте дополнительные типы к параметрам шаблона.
Предоставляя следующий сценарий, как я могу напрямую получить доступ к элементам Base из производного класса? Возможно ли это без указания полного типа базового класса?
#include <iostream>
template<class Derived, class X>
struct Base
{
void set_a( int a ) { _a = a; }
protected:
int _a;
};
template<class X>
struct Derived: public Base<Derived<X>, X>
{
int get_a( )
{
// return Base<Derived<X>,X>::_a; // This works!
return _a; // error: use of undeclared identifier '_a'
}
};
struct foo;
int main()
{
Derived<foo> test;
auto base_p = static_cast< Base<Derived<foo>, foo>* >( &test );
base_p->set_a( 42 );
int a = test.get_a();
std::cout << a << std::endl;
}
g ++ 5.3.1 / clang ++ 3.8.0 вывод:
error: use of undeclared identifier '_a'
Вы можете добавить using
объявление в вашем классе:
template<class X>
struct Derived: public Base<Derived<X>, X> {
using Base<Derived<X>, X>::_a;
/* ... */
};
Вы все еще должны указать это один раз, хотя.
В Derived
объем, _a
не объявлено, но унаследовано, поэтому вы должны написать this->_a
искать в базовом классе или явно писать Base<Derived<X>, X>::_a
, Последний может быть импортирован с
using Base<Derived<X>, X>::_a;
в определении Derived
,
ТЛ; др
Если this->_a
написано, this
автоматически преобразуется в Base<Derived<X>, X>*
чтобы соответствовать внутренней operator->
,
Если только _a
написано, поиск безусловного имени выполняется. Неквалифицированный поиск имени основан на области, что не связано с наследованием. В вашем примере _a
в Derived::get_a
, так _a
ищется в
Derived::get_a
Derived
нет _a
найдено, что вызывает ошибку компиляции.