gpt4 book ai didi

c++ - 是否有可能摆脱模板特化以停止递归?

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:10:11 24 4
gpt4 key购买 nike

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

目前,我有一个模板迭代器类(使用 boost::iterator_facade),如果 L!= 0T&(存储的元素)如果 L==0。是否有可能将两者结合在一个类中,这样就需要更少的重复代码?

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;
};

最佳答案

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

(1) boost::iterator_facade() 继承类接收不同的参数。您可以按照 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 > >

(2) 构造函数中的 assert(stepsize()==1); 仅存在于地面 (L == 0U) 版本中。您可以将其修改为

assert( (L > 0U) || (stepsize() == 1) ); 

(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::size_t 中更改了 L)

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;
};

关于c++ - 是否有可能摆脱模板特化以停止递归?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43018422/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com