Как правильно определить частичную специализацию для структуры члена шаблонного класса?
Я получаю сообщение об ошибке при попытке добавить 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 ответ
Правильная вещь здесь - поместить псевдонимы типа в 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;
};
}