Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initializing boost::shared_ptr<std::vector<T>> with boost::shared_ptr<std::list<T>>

Tags:

c++

boost

I would like to initialize a boost::shared_ptr<std::vector<std::string> > vec in the constructor initialize list with an boost::shared_ptr<std::list<std::string> > list?

Is it possible?

I tried this:

Test.hpp

class Test
{
public:
    Test(boost::shared_ptr<std::list<std::string> > list);

private:
    boost::shared_ptr<std::vector<std::string> > vec;
};

Test.cpp

Test::Test(boost::shared_ptr<std::list<std::string> > list) : vec(list->begin(), list->end())
{
}

Part of error message:

Test.cpp: In constructor ‘Test::Test(boost::shared_ptr<std::list<std::basic_string<char> > >)’:
Test.cpp:6:85: error: no matching function for call to ‘boost::shared_ptr<std::vector<std::basic_string<char> > >::shared_ptr(std::list<std::basic_string<char> >::iterator, std::list<std::basic_string<char> >::iterator)’
like image 941
tmsblgh Avatar asked Aug 23 '16 11:08

tmsblgh


2 Answers

Replace:

vec(list->begin(), list->end())

with:

vec(boost::make_shared(list->begin(), list->end()))

Your constructor should looks like:

Test::Test(const boost::shared_ptr<std::list<std::string> >& list) :
    vec(boost::make_shared(list->begin(), list->end())){
}

Be aware that you are copying the data from the std::list to the std::vector.

If you want less expensive solution, you could move them using std::make_move_iterator. However, since you still using boost smart pointers, I think that you do not have access to it.

Edit:

if it did not work try this:

vec(boost::make_shared<std::vector<std::string>>(list->begin(), list->end()))

Edit 2:

In order to cover the nullptr case as it was mentioned by @Maxim Egorushkin:

class Test{
public:
    Test(const boost::shared_ptr<std::list<std::string> >& list);

private:
    boost::shared_ptr<std::vector<std::string> > convert_to_vec(const boost::shared_ptr<std::list<std::string> >& lst) const;
    boost::shared_ptr<std::vector<std::string> > vec;
};

//in .cpp
Test::Test(const boost::shared_ptr<std::list<std::string> >& list):
    vec(convert_to_vec(list)){
}
boost::shared_ptr<std::vector<std::string> > Test::convert_to_vec(const boost::shared_ptr<std::list<std::string> >& lst) const{
    if(lst!=nullptr){
        return boost::make_shared<std::vector<std::string>>(list->begin(), list->end());
    }
    return nullptr;
}
like image 129
Humam Helfawi Avatar answered Oct 20 '22 17:10

Humam Helfawi


As a side note: it is not clear why the constructor takes shared_ptr<X> but does not use the shared_ptr<X>. It should take X& instead. Avoid using smart-pointers if possible.

Ideally, your code should look like:

class Test
{
public:
    Test(std::list<std::string> const& list)
        : vec(list.begin(), list.end())
    {}

private:
    std::vector<std::string> vec;
};
like image 23
Maxim Egorushkin Avatar answered Oct 20 '22 18:10

Maxim Egorushkin