Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 有没有可能摆脱模板专门化来停止递归?_C++_Templates_C++14_Template Meta Programming_Template Specialization - Fatal编程技术网

C++ 有没有可能摆脱模板专门化来停止递归?

C++ 有没有可能摆脱模板专门化来停止递归?,c++,templates,c++14,template-meta-programming,template-specialization,C++,Templates,C++14,Template Meta Programming,Template Specialization,我正在编写自己的容器类,它还提供迭代器。可以取消引用这些迭代器,然后显示原始容器的子范围,可以再次获得该子范围的迭代器 目前,我有一个模板迭代器类(使用boost::iterator_facade),如果L=如果L==0,则为0或到T&(存储元素)。是否可以在一个类中合并这两个类,从而减少重复代码的需要 template<typename T, int L> class CollectionIter : public boost::iterator_facade<

我正在编写自己的容器类,它还提供迭代器。可以取消引用这些迭代器,然后显示原始容器的子范围,可以再次获得该子范围的迭代器

目前,我有一个模板迭代器类(使用
boost::iterator_facade
),如果
L=如果
L==0
,则为0或到
T&
(存储元素)。是否可以在一个类中合并这两个类,从而减少重复代码的需要

template<typename T, int L>
class CollectionIter : public boost::iterator_facade<
        CollectionIter<T,L>, // type it selfe
        Collection<T,L-1>, // value type
        boost::random_access_traversal_tag,
        Collection<T,L-1> > // deref. type
{
public:
    CollectionIter(T* ptr, const std::vector<int>& collectionSize_)
        : pointer(ptr), collectionSize(collectionSize_) { }
    T* element() { return pointer; }
private:
    friend class boost::iterator_core_access;
    bool equal(const CollectionIter<T,L>& other) const { return pointer==other.pointer; }
    auto dereference() const { return Collection<T,L-1>(pointer, collectionSize); }
    void increment() { pointer = pointer + stepsize(); }
    void decrement() { pointer = pointer - stepsize(); }
    void advance(size_t i) { pointer = pointer + i*stepsize(); }
    auto distance_to(const CollectionIter<T,L>& other) { return (other.pointer - pointer)/stepsize(); }

    int stepsize() { return collectionSize.at(L); }

    T* pointer;
    const std::vector<int>& collectionSize;
};

/* Groundlevel Collection: deref returns T& */
template<typename T>
class CollectionIter<T,0> : public boost::iterator_facade<
        CollectionIter<T,0>,
        T,
        boost::random_access_traversal_tag >
{
public:
    CollectionIter(T* ptr, const std::vector<int>& collectionSize_)
        : pointer(ptr), collectionSize(collectionSize_) { assert(stepsize()==1); }
    T* element() { return pointer; }

private:
    friend class boost::iterator_core_access;
    bool equal(const CollectionIter<T,0>& other) const { return pointer==other.pointer; }
    T& dereference() const { return *pointer; }
    void increment() { pointer = pointer + stepsize(); }
    void decrement() { pointer = pointer - stepsize(); }
    void advance(size_t i) { pointer = pointer + i*stepsize(); }
    auto distance_to(const CollectionIter<T,0>& other) { return (other.pointer - pointer)/stepsize(); }

    int stepsize() { return collectionSize.at(0); }

    T* pointer;
    const std::vector<int>& collectionSize;
};
模板
类集合iter:public boost::iterator\u facade<
CollectionIter,//键入它selfe
集合,//值类型
boost::随机访问遍历标记,
集合>//deref。类型
{
公众:
CollectionIter(T*ptr,const std::vector&collectionSize_u2;)
:指针(ptr),集合大小(集合大小){
T*元素(){返回指针;}
私人:
朋友类boost::迭代器\u核心\u访问;
bool equal(const CollectionIter&other)const{return pointer==other.pointer;}
自动取消引用()常量{返回集合(指针,集合大小);}
无效增量(){pointer=pointer+stepsize();}
无效减量(){pointer=pointer-stepsize();}
void advance(size_t i){pointer=pointer+i*步长();}
自动距离(const CollectionIter&other){return(other.pointer-pointer)/stepsize();}
int stepsize(){return collectionSize.at(L);}
T*指针;
const std::vector&collectionSize;
};
/*地面收集:deref返回T&*/
模板
类集合iter:public boost::iterator\u facade<
收藏家,
T
boost::随机访问遍历标记>
{
公众:
CollectionIter(T*ptr,const std::vector&collectionSize_u2;)
:指针(ptr),collectionSize(collectionSize_512;){assert(stepsize()=1);}
T*元素(){返回指针;}
私人:
朋友类boost::迭代器\u核心\u访问;
bool equal(const CollectionIter&other)const{return pointer==other.pointer;}
T&dereference()常量{return*pointer;}
无效增量(){pointer=pointer+stepsize();}
无效减量(){pointer=pointer-stepsize();}
void advance(size_t i){pointer=pointer+i*步长();}
自动距离(const CollectionIter&other){return(other.pointer-pointer)/stepsize();}
int stepsize(){return collectionSize.at(0);}
T*指针;
const std::vector&collectionSize;
};

我在两个版本的
CollectionIter中只看到三个区别:

(1) 继承的类接收不同的参数。您可以使用Johannes Schaub建议的
std::conditional
解决这个问题;差不多

   public std::conditional< (L > 0U),
              boost::iterator_facade<
                 CollectionIter<T, L>,
                 Collection<T, L-1U>,
                 boost::random_access_traversal_tag,
                 Collection<T, L-1U> >,
              boost::iterator_facade<
                 CollectionIter<T, 0U>,
                 T,
                 boost::random_access_traversal_tag > >
(3) 递归
dereference()
方法在地面版本中确实不同。我不是SFINAE的专家,但是,如果我没有错的话,您可以按如下方式插入这两个

  template <int M = L, typename = std::enable_if_t<(M > 0U)>>
  auto dereference () const
   { return Collection<T, L-1U>(pointer, collectionSize); }

  template <int M = L, typename = std::enable_if_t<(M == 0U)>>
  T & dereference () const
   { return *pointer; }

在不深入研究代码的情况下,您似乎希望在代码中的某个地方应用
std::conditional
,以避免重复并仍然获得正确的继承。
  template <int M = L, typename = std::enable_if_t<(M > 0U)>>
  auto dereference () const
   { return Collection<T, L-1U>(pointer, collectionSize); }

  template <int M = L, typename = std::enable_if_t<(M == 0U)>>
  T & dereference () const
   { return *pointer; }
template <typename T, std::size_t L>
class CollectionIter :
   public std::conditional< (L > 0U),
              boost::iterator_facade<
                 CollectionIter<T, L>,
                 Collection<T, L-1U>,
                 boost::random_access_traversal_tag,
                 Collection<T, L-1U> >,
              boost::iterator_facade<
                 CollectionIter<T, 0U>,
                 T,
                 boost::random_access_traversal_tag > >
 {
   public:
      CollectionIter (T * ptr, const std::vector<int> & collectionSize_)
         : pointer(ptr), collectionSize(collectionSize_)
          { assert( (L > 0U) || (stepsize() == 1) ); }

      T* element() { return pointer; }

   private:
      friend class boost::iterator_core_access;

      bool equal (const CollectionIter<T, L> & other) const
       { return pointer==other.pointer; }

      template <int M = L, typename = std::enable_if_t<(M > 0U)>>
      auto dereference () const
       { return Collection<T, L-1U>(pointer, collectionSize); }

      template <int M = L, typename = std::enable_if_t<(M == 0U)>>
      T & dereference () const
       { return *pointer; }

      void increment ()
       { pointer = pointer + stepsize(); }

      void decrement()
       { pointer = pointer - stepsize(); }

      void advance (size_t i)
       { pointer = pointer + i*stepsize(); }

      auto distance_to (const CollectionIter<T, L> & other)
       { return (other.pointer - pointer)/stepsize(); }

      int stepsize()
       { return collectionSize.at(L); }

      T * pointer;

      const std::vector<int> & collectionSize;
 };