首页 文章

使用nullptr而不是end iterator

提问于
浏览
0

我想知道是否可以使用nullptr或某种通用的结束迭代器 .

例如:

// a.b->cdef().g->bdf() is a std::map<int, int>
std::unordered_map<int, int> copy(a.b->cdef().g->bdf().begin(), a.b->cdef().g->bdf().end());

您通常会编写以指定初始化新 Map 的开始和结束 .

如果我只想复制整个 Map ,为什么还需要指定结束标记 .

我更喜欢这样的东西:

std::unordered_map<int, int> copy(a.b->cdef().g->bdf().begin(), nullptr);

要么

std::unordered_map<int, int> copy(a.b->cdef().g->bdf().begin());

要么

std::unordered_map<int, int> copy(a.b->cdef().g->bdf().begin(), std::unordered_map::end);

edit :我将示例从std :: list <int>更改为std :: unordered_map <int,int> . 从std :: map到std :: unordered_map没有复制构造函数 .

3 回答

  • 5

    在STL中复制范围主要是使用一对迭代器来指定的 . 这是因为大多数复制操作都需要是有限的,并且很难使用单个迭代器指定有限范围 .

    nullptr 不是任何标准容器将返回的迭代器,并且不提供替代方法 .

    替代方案包括添加一个辅助函数,该函数接受容器作为参数(最好通过引用) . 然后可以从那些容器中提取迭代器,而不用大惊小怪 .

    最好的选择几乎肯定是改进您的基本设计和编码技术,以避免代码明确地通过过多的嵌套结构来查找数据(例如 a.b->cdef().g->bdf() ) . 简单易读的代码更易于理解,因此更容易理解 .

  • 0

    要回答问题,“是否可以使用nullptr而不是end()?”

    没有 .

    请考虑如何实现容器和迭代器 . 容器知道它的开始和结束迭代器 . 迭代器知道如何递增,递减并将自身与另一个迭代器进行比较 .

    所以以矢量为例 . begin迭代器如何知道停止递增的位置? iter == nullptr 如何知道何时返回true以便它可以停止?

    或者采用循环链表 . 它没有真正的结局 . 它只在迭代器再次等于begin迭代器时停止 . nullptr甚至意味着什么结束?

    如果你考虑实施,你会明白为什么答案是“不” .

  • 1

    如果要将整个容器的内容复制到不同类型的容器中,可以使用辅助函数

    template<typename InputIterRange, typename OutputIter>
    OutputIter range_copy(InputIterRange&& range, OutputIter out_iter)
    {
      return std::copy(range.begin(), range.end(), out_iter);
    }
    

    只要每个容器的 value_type 可以相互转换,这就可以工作 . 使用示例:

    int main() {
        std::set<int> a{1,2,3,4,5};
        std::unordered_set<int> b {11,22,33};
        range_copy(a, std::inserter(b, b.end()));
    }
    

相关问题