Re: Определение типа данных в потомке
От: Acteon  
Дата: 11.05.10 09:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Добрый день. После долго программирования ATL соорудил следующую конструкцию.

А>
А>template<typename T>
А>struct Base
А>{
А>    typename T::X m_x;
А>    void foo()
А>    {
А>        ((T *)this)->bar();
А>    }
А>};

А>struct A : public Base<A>
А>{
А>    typedef int X;
А>    void bar()
А>    {
А>    }
А>};
А>


А>По идее это обязывает в структуре A определить тип данных X, а переменная этого типа будет определена в предке. Использоваться m_x будет в потомке. Понимаю, что изврат, но это не компилируется. Функции потомка можно использовать при шаблонном наследовании, а типы — нет. Почему?


Почему, уже вроде объяснили. Пригодится ли, но есть такое решение:

template<typename T>
struct ATraits
{};

template<typename T>
struct Base
{
    typename ATraits<T>::X m_x;
    void foo()
    {
        ((T *)this)->bar();
    }
};

class A;

template<>
struct ATraits<A>
{
    typedef int X;
};

struct A : public Base<A>
{
    typedef ATraits<A>::X X;
    void bar()
    {
    }
};
Re[2]: Маленькое замечание
От: serge_levin Россия  
Дата: 12.05.10 15:40
Оценка: 5 (1)
Здравствуйте, rg45, Вы писали:

R>Очень опасная строчка:

R>
R>  ((T *)this)->bar();
R>

R>С ее помошью легко можно привести к типу, вовсе не являющемуся потомком.


R>Гораздо безопаснее так:

R>
R>  static_cast<T*>(this)->bar();
R>

R>В таком случае от ошибки убережет компилятор.

Не спасает от извращенного способа прострелить себе ногу по невнимательности.

template< class Derived >
struct Base
{
  void f()
  {
    static_cast< Derived* >( this )->DoF();
  }
};

struct a1 : public Base< a1 >
{
  void DoF()
  {
    LOGF();
  };
};

struct a2 : public Base< a1 >
{
};

int main()
{
  a2 a;
  a.f();
}
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.