Параметры шаблона не используются при частичной специализации - PullRequest
4 голосов
/ 19 июня 2011

У меня есть следующий код:

template<typename T, typename Allocator = std::allocator<T> >
class Carray {
    // ...
    typedef T* pointer;
    typedef pointer iterator;
    // ...
};

Теперь я пытаюсь сделать частичную специализацию для iterator_traits.Мне кажется, что все в порядке, но g ++ 4.4.5 жалуется:

#include <iterator>

namespace std {
    template<typename T, typename Allocator>
    struct iterator_traits<typename Carray<T, Allocator>::iterator> { // line 128
        typedef T value_type;
        typedef typename Allocator::difference_type difference_type;
        typedef typename Allocator::reference reference;
        typedef typename Allocator::pointer pointer;
        typedef typename std::random_access_iterator_tag iterator_category;
    };
}

Это полное сообщение об ошибке:

carray.h:128: error: template parameters not used in partial specialization:
carray.h:128: error:         ‘T’
carray.h:130: error: ‘Allocator’ has not been declared
carray.h:131: error: ‘Allocator’ has not been declared
carray.h:132: error: ‘Allocator’ has not been declared

1 Ответ

10 голосов
/ 19 июня 2011

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

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

Рассмотрим, что произойдет в следующем упрощенном сценарии:

template <typename T> struct S { typedef int type; };

template <typename T> 
struct Traits { };

template <typename T> 
struct Traits<typename S<T>::type> { };

Как компилятор должен знать, что T подключить к S или действительно ли подразумевается какой-то S<T>::type вместо int?

Проблема в том, что вложенный typedef (::type) зависит от параметра шаблона (T). Когда это имеет место в списке аргументов функции или в частичной специализации, тип T не может быть выведен (это «не выводимый контекст»).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...