2010-02-15 39 views
3

的集合上使用boost.assign考慮下面的代碼片段:上的shared_ptr

class Foo { 
public: 
    Foo(int Value); 

    // other stuff 
}; 

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

這不起作用開箱即用。做這項工作最簡單的方法是什麼?或者有什麼方法可以將值分配給ListOfFoo那麼簡單?

+0

你只需選擇喜歡的例子這或者是連續的數字?在這種情況下,我會建議使用std :: transform,boost :: counting_iterator和綁定在boost :: shared_ptr和構造函數(也許與lambda)。 –

回答

3

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); 
} 
+0

非常好,就是我在找的東西。我想知道,如果有更簡單的方法使用list_inserter類。文檔說它是擴展庫的關鍵,但我無法弄清楚如何使用它。 –

+0

@Space cowboy - 'list_inserter'就是你在設計一個新的容器類時所使用的,並且你希望它與Boost.Assign很好地相互作用(例如,使't + = 2,3'你的班級的一個實例)。但我認爲這不會有任何用處。 – Manuel

+0

謝謝你的清理。這是最後的答案。 –

1
std::list<boost::shared_ptr<Foo> > ListOfFoo = boost::assign::list_of(boost::make_shared<Foo>(1))(boost::make_shared<Foo>(2)); 

沒有從Foo*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 

你想要的是什麼不可能的,你必須明確地創建共享指針,並把它們傳遞給list_of

+0

感謝您的建議,但每次調用make_shared看起來都很難看。我希望它像給出的例子一樣易於閱讀。 –

1

您的boost :: list_of需要boost::shared_ptr<Foo>類型的對象。所以,你可以如下做到這一點:

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

和尼古拉一樣。我希望有一種方法可以告訴list_of從它給出的值構造共享指針。 –

+0

尼古拉在他的最新答案中提到,我不認爲這是可能的。我認爲他的boost :: make_shared解決方案非常優雅。 – Yukiko

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

也許看起來更好,如果該列表是要更大。