Как «разыменовать тип» в C ++ 03? - PullRequest
5 голосов
/ 05 сентября 2011

Как мне получить «разыменованный тип» другого типа в C ++ 03? Обратите внимание, что это может быть другой разыменованный тип, например std::vector<int>::iterator.

например. если у меня есть

template<typename T>
struct MyPointer
{
    T p;
    ??? operator *() { return *p; }
};

Как узнать, чем заменить ????

( Без ускорения ! Я хочу знать, как самому разобраться.)

Ответы [ 4 ]

11 голосов
/ 05 сентября 2011
template<typename>
struct dereference;

template<typename T>
struct dereference<T*>
{
    typedef typename T type;
};

template<typename T>
struct MyPointer
{
    T p;
    typename dereference<T>::type operator *() { return *p; }
};
2 голосов
/ 05 сентября 2011

В общем случае вы не можете.Для необработанных указателей вы можете частично специализироваться, как показано в других ответах - настраиваемые интеллектуальные указатели могут иметь общий typedef для типа результата.Однако вы не можете написать одну функцию, которая справится с любым указателем в C ++ 03.

1 голос
/ 23 января 2013

У вас может быть простая конструкция, которая рекурсивно удаляет все указатели из данного типа, как показано ниже:

template<typename T>
struct ActualType { typedef T type; };
template<typename T>
struct ActualType<T*> { typedef typename ActualType<T>::type type; };

Ниже приведена встроенная функция-обертка для рекурсивного поиска действительного значения по заданному типу указателя или не указателя;

template<typename T>
typename ActualType<T>::type ActualValue (const T &obj) { return obj; }
template<typename T>
typename ActualType<T>::type ActualValue (T *p) { return ActualValue(*p); }

И просто используйте его как:

template<typename T>
struct MyPointer
{
  T p;
  typename ActualType<T>::type operator *() { return ActualValue(p); }
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^                       ^^^^^^^^^^^^^^
};

В этом примере он удаляет все указатели из данного типа, но в соответствии с необходимостью вы можете настроить ActualType<> и ActualValue<>. Не будет никакой ошибки компилятора, даже если вы объявите MyPointer<> с не указателем типа.

Вот рабочая демоверсия для одного указателя и без типов указателей.

0 голосов
/ 05 сентября 2011

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

template<typename T>
struct MyPointer<T*>
{
    T* p;
    T operator*() { return *p; }
}
...