Reputation: 76778
Consider the following snippet:
class Foo {
public:
Foo( int Value );
// other stuff
};
std::list< boost::shared_ptr< Foo > > ListOfFoo = list_of( 1 )( 2 )( 3 )( 4 )( 5 );
This does not work out of the box. What is the simplest way to make this work, or is there any method to assign values to ListOfFoo
as simple as that?
Upvotes: 3
Views: 1039
Reputation: 13099
boost::assign::ptr_list_of
lets you construct a Boost pointer container with a very simple syntax. You can extend it through private inheritance so that it lets you create containers of shared_ptr
:
template< class T >
struct shared_ptr_list : boost::assign_detail::generic_ptr_list<T>
{
typedef boost::assign_detail::generic_ptr_list<T> Base;
template< class Seq >
operator Seq() const
{
Seq result;
for(typename Base::impl_type::iterator it = Base::values_.begin(), e = Base::values_.end(); it != e; ++it)
result.push_back(typename Seq::value_type(&*it));
Base::values_.release().release();
return result;
}
template< class U >
shared_ptr_list& operator()( const U& u )
{
return (shared_ptr_list&)boost::assign_detail
::generic_ptr_list<T>::operator()(u);
}
};
template< class T, class U >
shared_ptr_list<T> shared_ptr_list_of( const U& t )
{
return shared_ptr_list<T>()(t);
}
It looks a bit ugly but then it's really convenient to use:
int main()
{
using boost::shared_ptr;
std::deque<shared_ptr<Foo> > deq = shared_ptr_list_of<Foo>(1)(2)(3);
}
Upvotes: 3
Reputation: 8834
Another way would be to use std::transform
on an array of arguments:
const unsigned DataSize = 5;
int data[DataSize] = {1, 2, 3, 4, 5};
std::list<boost::shared_ptr<Foo> > ListOfFoo;
std::transform(data, data + DataSize, std::back_inserter(ListOfFoo), &boost::make_shared<Foo, int>);
Perhaps looks nicer if the list is to be even larger.
Upvotes: 2
Reputation: 26873
std::list<boost::shared_ptr<Foo> > ListOfFoo = boost::assign::list_of(boost::make_shared<Foo>(1))(boost::make_shared<Foo>(2));
There is no implicit conversion from Foo*
to shared_ptr<Foo>
.
shared_ptr<Foo> ptr = new Foo(1); // you can't do this
shared_ptr<Foo> ptr(new Foo(1)); // this is ok
shared_ptr<Foo> ptr = make_shared<Foo>(1); // this is also ok
What you want is impossible, you have to explicitly create shared pointers and pass them to list_of
.
Upvotes: 1
Reputation: 1123
Your boost::list_of requires objects of type boost::shared_ptr<Foo>
. So you could do it as follows:
typedef boost::shared_ptr<Foo> FooPtr;
std::list<boost::shared_ptr<Foo> > fooList = list_of
(FooPtr(new Foo(1))
(FooPtr(new Foo(2))
(FooPtr(new Foo(3));
Upvotes: 1