我有一个类,其中包含boost::shared_ptrs
到另一个类的对象的列表。shared_ptr的容器,但迭代原始指针
允许访问列表中的元素的类成员函数返回原始指针。为了一致性,我还希望能够使用raw指针而不是shared_ptrs进行迭代。所以当我解引用列表迭代器时,我想获取原始指针,而不是shared_ptr
。
我想我需要为此编写一个自定义迭代器。它是否正确?如果有的话可以有人指出我正确的方向 - 我从来没有这样做过。
我有一个类,其中包含boost::shared_ptrs
到另一个类的对象的列表。shared_ptr的容器,但迭代原始指针
允许访问列表中的元素的类成员函数返回原始指针。为了一致性,我还希望能够使用raw指针而不是shared_ptrs进行迭代。所以当我解引用列表迭代器时,我想获取原始指针,而不是shared_ptr
。
我想我需要为此编写一个自定义迭代器。它是否正确?如果有的话可以有人指出我正确的方向 - 我从来没有这样做过。
下面是一个使用Boost transform_iterator一个选项:
#include <list>
#include <boost/iterator/transform_iterator.hpp>
#include <tr1/memory>
#include <tr1/functional>
using std::list;
using std::tr1::shared_ptr;
using boost::transform_iterator;
using boost::make_transform_iterator;
using std::tr1::mem_fn;
using std::tr1::function;
struct Foo {};
struct Bar
{
typedef shared_ptr<Foo> Ptr;
typedef list<Ptr> List;
typedef function< Foo* (Ptr) > Functor;
typedef transform_iterator< Functor, List::iterator > Iterator;
Iterator begin()
{
return make_transform_iterator(fooptrs.begin(), mem_fn(&Ptr::get));
}
Iterator end()
{
return make_transform_iterator(fooptrs.end(), mem_fn(&Ptr::get));
}
List fooptrs;
};
C++ 11就可以很容易地消除function
包装,但我没有方便的编译器来测试它。你也可以使用类型擦除,如果你认为有必要隐藏了具体类型的Iterator
(我认为Adobe提供免费的any_iterator
类模板用于此目的。)
+1,如果获得引用而不是指针是可以接受的(我不明白为什么它不应该是这样),Boost也带有['indirect_iterator <>'](http://www.boost.org/库/迭代器/ DOC/indirect_iterator.html)。 – ildjarn 2012-04-05 22:11:44
完美。很好的例子,很好的答案。 – 2012-04-07 00:01:35
我有时看到有人伸手的boost::shared_ptr
STL容器时,实际上不太明显且相对较少的已知boost::ptr_container
可能是更好的选择。
这可能是也可能不是这种情况之一,但考虑到ptr_container
类的一个很好的属性是它们的迭代器有an "extra" indirection,这有助于保持事物的清洁和安全。
是的,这是真的。然而,在这种情况下,实际上会共享所有权。 – 2012-04-05 23:59:30
请记住,'shared_ptr'就像常规指针('* p'和'p->'都做正确的事情)。 – GManNickG 2012-04-05 20:56:53
我可能是错的,但提供原始指针和智能指针看起来像是在寻找麻烦。特别是,如果原始指针允许写入。你在寻找什么样的迭代器?如果我是你,我可能会从最简单的例如'ForwardIterator'开始。 – dirkgently 2012-04-05 21:07:10
我知道'shared_ptr'与'* p'和'p->'表现得一样。有一段时间,我并没有真正意识到差异。但是当涉及到用户界面时,这是一个问题。 API中的其他函数将指针作为参数。因此,如果用户从迭代器获取对象,则需要使用'it-> get()'获取原始指针。我认为这并不重要,但从最终用户的角度来看,用户甚至不应该知道底层对象由'shared_ptr'保存。所以我想在整个图书馆中保持一致。 – 2012-04-05 21:14:26