【问题标题】:Using boost.assign on collection of shared_ptr在 shared_ptr 集合上使用 boost.assign
【发布时间】:2010-02-15 13:29:02
【问题描述】:

考虑以下 sn-p:

class Foo {
public:
    Foo( int Value );

    // other stuff
};

std::list< boost::shared_ptr< Foo > > ListOfFoo = list_of( 1 )( 2 )( 3 )( 4 )( 5 );

这不是开箱即用的。使这项工作最简单的方法是什么,或者有什么方法可以将值分配给ListOfFoo 这么简单?

【问题讨论】:

  • 你是选择这样的例子还是连续的?在这种情况下,我建议使用 std::transform、boost::counting_iterator 并绑定 boost::shared_ptr 和构造函数(可能使用 lambda)。

标签: c++ stl boost


【解决方案1】:

boost::assign::ptr_list_of 让您可以使用非常简单的语法构造Boost pointer container。你可以通过私有继承来扩展它,这样你就可以创建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);
}

看起来有点丑但是用起来真的很方便:

int main()
{
    using boost::shared_ptr;
    std::deque<shared_ptr<Foo> > deq = shared_ptr_list_of<Foo>(1)(2)(3);
}

【讨论】:

  • 非常好,正是我想要的。不过,我想知道是否有更简单的方法使用 list_inserter 类。文档说它是扩展库的关键,但我不知道如何使用它。
  • @Space cowboy - list_inserter 是您在设计一个新的容器类并且希望它与 Boost.Assign 良好交互时使用的对象(例如,使 t += 2, 3 与 @987654329 @ 是你的类的一个实例)。但我认为它在这里没有任何用处。
【解决方案2】:

另一种方法是在参数数组上使用std::transform

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>);

如果列表更大,也许看起来更好。

【讨论】:

    【解决方案3】:

    您的 boost::list_of 需要 boost::shared_ptr&lt;Foo&gt; 类型的对象。所以你可以这样做:

    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));
    

    【讨论】:

    • 和尼古拉一样。我希望有一种方法可以告诉 list_of 从给定的值构造共享指针。
    • 我认为这不可能,正如尼古拉在他更新的答案中提到的那样。我认为他的 boost::make_shared 解决方案非常优雅。
    【解决方案4】:
    std::list<boost::shared_ptr<Foo> > ListOfFoo = boost::assign::list_of(boost::make_shared<Foo>(1))(boost::make_shared<Foo>(2));
    

    没有从Foo*shared_ptr&lt;Foo&gt; 的隐式转换。

    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
    

    你想要的是不可能的,你必须显式创建共享指针并将它们传递给list_of

    【讨论】:

    • 感谢您的建议,但每次调用 make_shared 看起来都太难看了。我希望它像给定的示例一样易于阅读。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    • 2017-04-06
    • 2016-11-01
    • 2023-04-03
    • 2014-11-16
    相关资源
    最近更新 更多