相关疑难解决方法(0)

如何实现STL样式的迭代器并避免常见的陷阱?

我创建了一个集合,我想提供一个STL风格的随机访问迭代器.我正在寻找迭代器的示例实现,但我没有找到任何.我知道需要const重载[]*运算符.迭代器有什么要求是"STL风格",还有哪些其他缺陷需要避免(如果有的话)?

附加上下文:这是一个库,除非我真的需要,否则我不想引入任何依赖.我编写自己的集合,以便能够使用相同的编译器在C++ 03和C++ 11之间提供二进制兼容性(因此没有STL可能会破坏).

c++ iterator const-iterator

286
推荐指数
5
解决办法
17万
查看次数

正在弃用的std :: iterator的准备工作

3月21 ,标准委员会投票赞成批准P0174std::iterator提议的弃用:

对于读者而言,很长的void参数序列不仅仅是简单地typedef在类定义本身中提供预期的s,这是当前工作草案采用的方法,遵循设置的模式

之前std::iterator,鼓励继承从迭代器样板实现中删除乏味.但弃用将需要以下其中一项:

  1. 迭代器样板现在需要包含所有必需的typedefs
  2. 使用迭代器的算法现在需要使用auto而不是依赖于迭代器来声明类型
  3. 洛基阿斯塔曾建议std::iterator_traits,可以更新,而继承工作std::iterator

有人可以告诉我我应该期待哪些选项,因为我设计了自定义迭代器,着眼于兼容性?

c++ standards iterator deprecated c++17

58
推荐指数
2
解决办法
1万
查看次数

如何避免代码重复实现const和非const迭代器?

我正在实现一个具有STL类接口的自定义容器.我必须提供一个常规迭代器和一个const迭代器.两个版本的迭代器的大多数代码都是相同的.我怎样才能避免这种重复?

例如,我的容器类是Foo,我正在实现FooIteratorFooConstIterator.两个迭代器都必须提供operator++()相同的方法.

我的问题类似于如何删除类似的const和非const成员函数之间的代码重复?但是那个问题的答案特定于const和非const方法,尤其是访问器.我没有看到这可能会如何推广到迭代器问题.

我应该FooIteratorFooConstIterator其他非const方法派生并扩展它吗?这要么导致虚拟方法或方法隐藏,这在这里似乎不合适.

也许FooIterator应该包含一个FooConstIterator.虽然这种方法确实减少了实现重复,但它似乎重新引入了许多样板方法定义.

是否有聪明的模板技术从单个定义生成两个迭代器?或许有一种方法 - 颤抖 - 使用预处理器来消除这些几乎相同的类.

我已经尝试查看我的本地STL实现,看看它是如何处理它的.有很多辅助类,我在设计中遇到了麻烦,但看起来功能很简单.

在以前的项目中,我的自定义容器是在标准STL容器之上构建的,所以我不必提供自己的迭代器.在这种情况下,这不是一个选项.

c++ iterator const dry

52
推荐指数
2
解决办法
1万
查看次数

可以'iterator'类型只是子类'const_iterator'吗?

关于迭代器的另一个问题之后,我对自定义容器有一些疑问.在我的容器中,iterator是一个子类const_iterator,所以我从非const转换为const"免费".但这是允许的,还是有这样的设置有任何缺点或非工作方案?

c++ containers iterator casting

15
推荐指数
1
解决办法
3402
查看次数

static_assert用于确保设计合同

作为开发人员团队的一员,我想确保在我们发布的自定义迭代器上实现一组函数(和运算符).使用STL迭代器类型作为基本类型有帮助,但是由于某些原因(在我的控制范围之外),我们决定不强制执行STL兼容性.迭代器由同一团队和整个公司的人员使用.

我想设计一个消耗迭代器类型的模板类,并根据设计合同进行测试.

例如,我希望迭代器实现一个operator ++,operator--并声明所需的typedef.

1>是否可以实现强制设计合同的模板类?可能使用static_assert?

2>如果是,这是一个好的设计吗?

reference:自定义迭代器

c++ iterator

9
推荐指数
1
解决办法
2893
查看次数

仅在基于范围的循环中迭代奇数(偶数)元素

假设我们有一个普通数组(或其他支持基于范围的循环的容器):

const int N = 8;
int arr[N] = {0, 1, 2, 3, 4, 5, 6, 7};
Run Code Online (Sandbox Code Playgroud)

使用索引或迭代器,我们可以遍历奇数元素,将索引增加2:

for (int i = 0; i < N; i+=2)
{
   std::cout << arr[i] << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

如何使用基于范围的循环获得类似的结果并避免显式迭代器/索引或迭代跳过使用?就像是:

for (const auto& v: odd_only(arr))
{
   std::cout << v << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

您看到的简单而优雅的解决方案是什么?标准库是否包含类似的内容?

c++ c++11

8
推荐指数
1
解决办法
639
查看次数

如何在类中实现标准迭代器

我有一些类通常使用标准容器作为底层字段.例如,我有一个班级

template <typename T>
class Vec_3D
{
public:
    /* ... */
    std::array<T, 3> vec;
    /* ... */
};
Run Code Online (Sandbox Code Playgroud)

它只有一个变量vec,其余的只是我在处理矢量时需要的函数.我希望能够使用基于范围的for循环,例如

Vec_3D<double> vec;
for (double val : vec) {/*...*/}
Run Code Online (Sandbox Code Playgroud)

这应该是很容易迭代的std::array<double, 3>.

如何在我的类中实现迭代器,而这又应该调用迭代器std::array<T, 3>

我从这个问题开始,并尝试在我的类中定义迭代器

typedef std::iterator<std::random_access_iterator_tag, T, ptrdiff_t, T*, T&> iterator;
typedef std::iterator<std::random_access_iterator_tag, const T, ptrdiff_t, const T*, const T&> const_iterator;

inline iterator begin() noexcept { return vec.begin(); }
inline const_iterator cbegin() const noexcept { return vec.cbegin(); }
inline iterator end() noexcept { return …
Run Code Online (Sandbox Code Playgroud)

c++ iterator c++11

7
推荐指数
3
解决办法
9073
查看次数

在C ++ 17中实现迭代器和const_iterator的正确方法是什么?

在实现自定义容器时,我到了需要实现迭代器的地步。当然,我不想为const和non-const迭代器编写两次代码。我发现了这个问题,详细说明了这样的可能实现:

template<class T>
class ContainerIterator {
    using pointer = T*;
    using reference = T&;
    ...
};

template<class T>
class Container {
    using iterator_type = ContainerIterator<T>;
    using const_iterator_type = ContainerIterator<const T>;
}

Run Code Online (Sandbox Code Playgroud)

但是,我也发现了这个这个问题,使用模板参数:

template<class T, bool IsConst>
class ContainerIterator {
    using pointer = std::conditional_t<IsConst, const T*, T*>;
    using reference = std::conditional_t<IsConst, const T&, T&>;
    ...
};

template<class T>
class Container {
    using iterator_type = ContainerIterator<T, false>;
    using const_iterator_type = ContainerIterator<T, true>;
}
Run Code Online (Sandbox Code Playgroud)

第一个解决方案似乎更容易,但是答案是从2010年开始。经过一些研究,似乎第一个版本并未得到广泛使用,但我不知道为什么。我觉得我缺少第一个版本的一些明显缺陷。


因此问题变为:

  1. 第一个版本有什么问题吗?

  2. 如果没有,为什么版本#2似乎是c ++ …

c++ c++17

7
推荐指数
1
解决办法
115
查看次数

增量运算符/迭代器实现

我想弄清楚这里有几件事:

  1. 如何为具有指向下一个节点的指针的节点类编写增量运算符?
  2. 如何为下面的类实现迭代器?

    #include <iostream>
    #include <vector>
    using namespace std;
    
    template <typename T>
    class Node {
    public:
        Node(int i=0):val(i) {}
        Node*& operator++(int i=0) {return next;};
    
        T val;
        Node *next;
    };
    
    //================================================
    int main() {
    
        Node<int> *head, *tmp1, *tmp2;
    
        tmp1 = new Node<int>(0); 
        head = tmp1;
    
        for (int i=1; i<10; ++i) {
    
            tmp2 = new Node<int>(i);
            tmp1->next = tmp2;
            tmp1 = tmp2;
        }
    
        while (head != NULL) {
    
            cout << head->val << " '";
            head = head->operator++(0);    //How do I make …
    Run Code Online (Sandbox Code Playgroud)

c++ iterator linked-list post-increment

6
推荐指数
1
解决办法
1万
查看次数

是否可以重用通常的迭代器来构建const迭代器?

研究

我找到了这个老答案.我想知道解决方案是否仍然有效,或者是否有更新,更有效的方法.

背景

让我们假设我有一个像下面这样的迭代器(细节并不重要,只是它很大):

    class inorder_iterator : public std::iterator<std::forward_iterator_tag, token>
    {
        friend syntax_tree;

        node* current_node;
        std::stack<node*> prev_nodes;
        //std::stack<node*> visited_nodes;
        std::map<node*, bool> visited;
    public:
        inorder_iterator();

        inorder_iterator& operator++();
        inorder_iterator operator++(int);

        token& operator*();
        const token& operator*() const;

        token* operator->();
        const token* operator->() const;

        friend bool operator==(const inorder_iterator lhs, const inorder_iterator rhs);
        friend bool operator!=(const inorder_iterator lhs, const inorder_iterator rhs);

    private:
        inorder_iterator(node* current);
        node* find_leftmost_node(node* from);
    };
Run Code Online (Sandbox Code Playgroud)

问题

成员函数声明的实现具有合理的大小,但我想重用当前的迭代器来减少代码重复.

理念

想到的第一个想法就是在node类型上进行模板化,所以我可以通过const node使它成为const迭代器,但它听起来很腥

template <typename Node>
//replace every occurrence …
Run Code Online (Sandbox Code Playgroud)

c++ code-reuse const-iterator c++14

1
推荐指数
1
解决办法
318
查看次数