据我所知,在STL算法适用std::back_inserter
的任何地方,您都可以传递一个使用.end()
构造的std::inserter
:
就我所知,在STL算法中任何使用std::back_inserter
的地方,您都可以使用使用.end()
构造的std::inserter
代替:
std::copy(l.begin(), l.end(), std::back_inserter(dest_list));
std::copy(l.begin(), l.end(), std::inserter(dest_list, dest_list.end()));
与back_inserter
不同,据我所知inserter
适用于任何STL容器!!在到达这里之前,我已经成功地尝试了使用它来操作std::vector
、std::list
、std::map
和std::unordered_map
,感到非常惊讶。
我认为可能是因为对于某些结构,push_back
比insert(.end())
更快,但我不确定......
对于std::list
似乎并非如此(很合理):
// Copying 10,000,000 element-list with std::copy. Did it twice w/ switched order just in case that matters.
Profiling complete (884.666 millis total run-time): inserter(.end())
Profiling complete (643.798 millis total run-time): back_inserter
Profiling complete (644.060 millis total run-time): back_inserter
Profiling complete (623.151 millis total run-time): inserter(.end())
但是对于std::vector
,它确实略有不同,尽管我不太确定为什么:
// Copying 10,000,000 element-vector with std::copy.
Profiling complete (985.754 millis total run-time): inserter(.end())
Profiling complete (746.819 millis total run-time): back_inserter
Profiling complete (745.476 millis total run-time): back_inserter
Profiling complete (739.774 millis total run-time): inserter(.end())
我猜在一个向量中,相对于只是使用arr[count++],需要多一些开销来找出迭代器所在的位置并将元素插入其中。也许就是这个原因吧?
但仍然有疑问,那是主要原因吗?
我的后续问题是:"编写一个模板函数,然后期望将std::inserter(container, container.end())
用于(几乎)任何STL容器,这样可行吗?"
我更新了数字并切换到标准编译器。以下是我的编译器详细信息:
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
Target: x86_64-linux-gnu
我的构建命令:
g++ -O0 -std=c++11 algo_test.cc
我认为这个问题问的是我的问题的后半部分,即“我能否编写一个使用std::inserter(container, container.end())
并期望它适用于几乎每个容器的模板函数?”
那里的答案是“Yes, for every container except for std::forward_list
.”。但根据下面评论中和user2746253的回答中的讨论,听起来我应该知道这对于std::vector
来说会比使用std::back_inserter
慢...
因此,我可能希望为使用RandomAccessIterator
的容器专门特化我的模板,以使用back_inserter
代替。这有意义吗?谢谢。
back_inserter_iterator
调用push_back
,所以它当然不能适用于所有容器。另一方面,insert_iterator
调用insert
。这些操作的速度取决于你想要做什么。“适用于任何 STL 容器!”是错误的。也许C++ vector's insert & push_back difference会很有帮助。 - user3920237std::queue
。 - Ben Voigtstd::vector<T>
的inserter
需要T
是可移动赋值的,而back_inserter
则不需要。[Live example] (http://coliru.stacked-crooked.com/a/1b18eeb23c18b0e0) - dyp