C++11:使用 foreach 循环遍历智能指针
问题:
在 C++11 中,你想使用新的 for 循环语法遍历智能指针(auto_ptr、shared_ptr 等)集合,比如 std::vector。
让我们试试:
example.cpp
using namespace std;
shared_ptr<vector<int> > smartptr(/* A ptr to your vector */);
for(int s : smartptr) {
/* 做一些有用的事情 */
}尝试编译此代码时,GCC 发出以下错误消息(为简单起见省略其他行)
errors.txt
error: no matching function for call to 'begin(std::shared_ptr<std::vector<int> >&)'
error: no matching function for call to 'end(std::shared_ptr<std::vector<int> >&)'或者,当设置 LANG=de 时:
errors-de.txt
Fehler: keine passende Funktion für Aufruf von »begin(std::shared_ptr<std::vector<int> >&)«
Fehler: keine passende Funktion für Aufruf von »end(std::shared_ptr<std::vector<int> >&)«解决方案 1(推荐):
只需解引用指针(这有效因为 operator* 在智能指针上定义):
solution1.cpp
using namespace std;
shared_ptr<vector<int> > smartptr(/* A ptr to your vector */);
for(int s : *smartptr) {
/* 做一些有用的事情 */
}解决方案 2:
在你的源代码中 for 循环之前包含以下代码:
shared_ptr_begin_end.hpp
#include <memory>
template<typename T>
auto inline begin(std::shared_ptr<T> ptr) -> typename T::iterator {
return ptr->begin();
}
template<typename T>
auto inline end(std::shared_ptr<T> ptr) -> typename T::iterator {
return ptr->end();
}上面的源代码仅适用于共享指针,但你可以简单地将 std::shared_ptr 替换为 std::auto_ptr、std::weak_ptr 或你喜欢的任何类型,假设它可以使用 * 解引用。
此解决方案使你免于解引用指针,这可能是好是坏取决于你偏好的编码风格。根据你的编译器设置,额外的符号可能会或可能不会被优化掉(inline 关键字只是建议,对编译器不是强制性的),但在大多数情况下,你最终可能得到与使用解决方案 1 完全相同的速度。
为什么这有效?
上面的源代码仅适用于共享指针,但你可以简单地将 std::shared_ptr 替换为 std::auto_ptr、std::weak_ptr 或你喜欢的任何类型,假设它可以使用 * 解引用。
此解决方案使你免于解引用指针,这可能是好是坏取决于你偏好的编码风格。根据你的编译器设置,额外的符号可能会或可能不会被优化掉(inline 关键字只是建议,对编译器不是强制性的),但在大多数情况下,你最终可能得到与使用解决方案 1 完全相同的速度。
解决方案 3
如果你使用 boost::foreach,这可能对你有效,但如果编译器不优化它,解决方案相当慢。
它基于 boost::foreach 可以接受一对迭代器的事实。
boost_foreach_example.cpp
BOOST_FOREACH(string str, foreach_wrap_ptr(mySharedPtr)) {
//...
}Check out similar posts by category:
C/C++
If this post helped you, please consider buying me a coffee or donating via PayPal to support research & publishing of new posts on TechOverflow