使用nullptr而不是end iterator

时间:2015-04-29 08:37:13

标签: c++ stl

我想知道是否可以使用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());

是您通常用来指定初始化新地图的开始和结束的内容。

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

我更喜欢这样的东西:

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

编辑:我从std :: list&lt; int&gt;更改了示例到std :: unordered_map&lt; int,int&gt;。从std :: map到std :: unordered_map没有复制构造函数。

3 个答案:

答案 0 :(得分:5)

要回答问题,&#34;是否可以使用nullptr而不是end()?&#34;

没有

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

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

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

如果你考虑实施,你会明白为什么答案是&#34;否。&#34;

答案 1 :(得分: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()));
}

答案 2 :(得分:1)

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

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

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

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