我想知道是否可以使用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没有复制构造函数。
答案 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()
)。简单易读的代码更易于理解,因此更容易理解。