代码之家  ›  专栏  ›  技术社区  ›  Mordachai

如何正确定义模板类成员结构的部分专门化?

  •  0
  • Mordachai  · 技术社区  · 7 年前

    尝试为模板化成员结构添加std::iterator_traits时出错-即,我有一个iterator类,它是模板化外部类的成员:

    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::迭代器(即使是-Boost::迭代器适配器和lt;& gt;使其完全意义,实际上在这一和其他上下文中工作)…

    // 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版本7.7.3(为这个项目启用的C++ 17)抱怨:

    错误C27 64:“字符类型”:模板参数不使用或可部分地被部分化的STD::迭代器特征::迭代器& Gt;

    为什么不呢?

    我怀疑这是!由于试图部分地专门化一个成员结构而不是一个模板化结构,而不是在SubLuxInguleCullAdvult& Lt≫

    1 回复  |  直到 7 年前
        1
  •  2
  •   Caleth    7 年前

    正确的做法是将类型别名放入 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;
      };
    }