2010-06-17 3 views
2

Есть ли способ получить отложенный тип параметра шаблона класса?Как получить тип отложенного параметра шаблона

template <class TPtr> 
struct foo { 
    typedef TPtr ptr_type; 
    typedef ??? element_type; /* shall be the type of a deferred TPtr*/ 
}; 

так foo<const char*>::element_type результаты в const char и foo<std::vector<int>::iterator_type>::element_type результаты в int.

я отдаю себе отчет в том, что я могу использовать value_type ЬурейеЕ для C++ итераторы (как std::vector<int>::iterator_type::value_type), но сырые указатели нету получил value_type ЬурейеЕ, так что я не повезло там.

ответ

4

Если TPtr может быть указателем, вы ищете Boost's remove_pointer.

Если вы задаетесь вопросом, как в мире, который работает, он использует частичную специализацию в этой манере:

template<typename T> 
struct RemovePointer; 

template<typename T> 
struct RemovePointer<T*> 
{ 
    typedef T Type; 
}; 

int main() 
{ 
    RemovePointer<int*>::Type foobar; // foobar has the type int 
    return 0; 
} 

Если TPtr может быть либо итератор или указатель, вам нужно the iterator_traits class, который часть стандартной библиотеки. В вашем случае она используется так:

template <class TPtr> 
struct foo { 
    typedef TPtr ptr_type; 
    // The compiler won't know for sure if value_type is actually 
    // a type until TPtr is known. The typename keyword is a hint 
    // to the compiler so it doesn't cause an error. 
    typedef typename iterator_traits<TPtr>::value_type element_type; 
}; 

Верьте или нет, он работает по частичной специализации, а также. Это в основном определяется следующим образом:

// Primary template for iterators 

template<class Iterator> 
struct iterator_traits 
{ 
    typedef typename Iterator::difference_type difference_type; 
    typedef typename Iterator::value_type value_type; 
    typedef typename Iterator::pointer pointer; 
    typedef typename Iterator::reference reference; 
    typedef typename Iterator::iterator_category iterator_category; 
}; 

// Partial specializations for pointers 

template<class T> 
struct iterator_traits<T*> 
{ 
    typedef ptrdiff_t difference_type; 
    typedef T value_type; 
    typedef T* pointer; 
    typedef T& reference; 
    typedef random_access_iterator_tag iterator_category; 
}; 

template<class T> 
struct iterator_traits<const T*> 
{ 
    typedef ptrdiff_t difference_type; 
    typedef T value_type; 
    typedef const T* pointer; 
    typedef const T& reference; 
    typedef random_access_iterator_tag iterator_category; 
}; 

Вот почему iterator_traits класс работает как на итераторы и указатели.

+0

это работает на итераторах? – smerlin

+0

Используйте итерационное решение для более общего подхода. Он будет работать с указателями. – GManNickG

+0

Я отредактировал свой ответ, чтобы включить решение, применимое к итераторам. –