Как правильно определить частичную специализацию для структуры члена шаблонного класса? - PullRequest
0 голосов
/ 06 июня 2018

Я получаю сообщение об ошибке при попытке добавить std :: iterator_traits для шаблонной структуры-члена - т.е. у меня есть класс итератора, который является членом шаблонного внешнего класса:

namespace Toolbox {
    template <typename CharType>
    class substring_container_adapter
    {
    public:
        struct iterator // : public std::iterator<std::forward_iterator_tag, const CharType *>   C++ 17 is very upset at this approach!
        {
            // iterator constructor
            iterator(const CharType * pszPosition, const CharType * pszDelimeters)

Позже япопробуйте добавить частичную специализацию для свойств итератора в std, потому что, очевидно, наследование от std :: iterator устарело (даже если это - или boost :: iterator_adaptor <> имеет смысл и фактически работает в этом и других контекстах) ...

// define iterator traits for our custom iterators
namespace std 
{
    template <typename CharType>
    struct iterator_traits<class Toolbox::substring_container_adapter<CharType>::iterator>
    {
        using iterator_category = forward_iterator_tag;
        using value_type = CharType;
    };
}

Однако VC ++ 2017 версии 15.7.3 (C ++ 17 включен для этого проекта) жалуется:

ошибка C2764: «CharType»: параметр шаблона не используется или выводится при частичной специализации'std :: iterator_traits :: iterator>'

Почему бы и нет?

Я подозреваю, что это раздражающее ограничение! @ # $ из-за попытки частичной специализации структуры члена вместошаблонная структура вне substring_container_adapter <>?

1 Ответ

0 голосов
/ 06 июня 2018

Правильно сделать здесь: поместить псевдонимы типа в iterator, а не пытаться частично специализировать std::iterator_traits.

namespace Toolbox {
    template <typename CharType>
    class substring_container_adapter
    {
    public:
        struct iterator // : public std::iterator<std::forward_iterator_tag, const CharType *>   C++ 17 is very upset at this approach!
        {
            using iterator_category = forward_iterator_tag;
            using value_type = const CharType *;
            using reference = const CharType * &;
            using pointer = const CharType * *;
            using difference_type = std::ptrdiff_t;

            // iterator constructor
            iterator(value_type pszPosition, value_type pszDelimeters)

            // ...
        }
    }
}

Основная причина осудить std::iterator состоит в том, что комитету не понравилось впечатление, которое он создал, что все Iterators должны происходить из него, поскольку ни один из итераторов контейнера не требуется.Вы можете определить точную замену

namespace not_std {
  template<class Category, class T, class Distance = ptrdiff_t,
           class Pointer = T*, class Reference = T&>
  struct iterator {
    using iterator_category = Category;
    using value_type        = T;
    using difference_type   = Distance;
    using pointer           = Pointer;
    using reference         = Reference;
  };
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...