- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在编写我自己的容器类,它也提供迭代器。这些迭代器可以被取消引用,然后显示原始容器的子范围,再次可以获得迭代器。
目前,我有一个模板迭代器类(使用 boost::iterator_facade
),如果 L!= 0
或 T&
(存储的元素)如果 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/
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 4 年前。
正如您在 this travis.yml 中看到的那样文件,我的代码依赖于一些第三方库,我在构建项目之前将它们安装在远程系统上。 Travis 每次推送提交时都会下载并构建这些库,这可以避免吗?我的意
我是一名优秀的程序员,十分优秀!