Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Placing smart pointers in an STL container

I have a container which I'd like to fill with pointers to class C. However, I'd rather use Boost shared_ptr than dumb pointers.

I declare the container as container<C*>, but then get this error:

  no known conversion for argument 1 from ‘boost::shared_ptr<C>’ to ‘C* const&’

How should I declare the container to take boost shared ptrs? If possible, I'd like it to take dumb pointers as well.


UPDATE: From the responses, it seems that the container must indeed be declared to take smart pointers, it can't be made to take both smart or dumb pointers. That is, there's no coercion from smart to dumb or versa. Is that correct?

like image 634
SRobertJames Avatar asked Nov 23 '25 05:11

SRobertJames


2 Answers

Here is a simple working demo using C++11 shared pointers. They are analogous to Boost shared pointers.

#include <iostream>
#include <memory>
#include <vector>

int main( int argc, char* argv[] )
{
    // Create vector
    std::vector<std::shared_ptr<int>> buffer;

    for( int i=0; i<10; i++ )
        buffer.push_back(std::make_shared<int>(i));

    for( int i=0; i<10; i++ )
        if( (*buffer[i]) != i ){
            std::cout << "Match invalid for " << i << "." << std::endl;
            return 1;
        }
    std::cout << "Valid result" << std::endl;

    return 0;
}

I compiled this using

g++ main.cpp -o main -std=c++11
like image 86
msmith81886 Avatar answered Nov 24 '25 22:11

msmith81886


In order to use vectors you need to explicitly specify the type of objects that they will be holding.In your case it will be boost::shared_ptr. I also understand that you want to store dumb pointers in that container. You probably mean raw pointers.As mentioned earlier your container can primarily store one type however there are exceptions for instance the types are related via inheritance or another mechanism (such as serialization) for which some explicit down-casting would be required when you attempt to use those objects or the type is a generic type. Never the less. Here is another approach. You don't need a vector that stores both a smart pointer and a raw pointer since you could always obtain a raw/dumb pointer from a smart pointer. Your best approach is to create a vector like this

std::vector<boost::shared_ptr<foo>> vec;

The above creates a vector that will store shared pointers to foo.

Then when ever you have a shared pointer as such

 boost::shared_ptr<foo> foo_ptr(new foo());

You can do something like this

vec.push_back(foo_ptr)

When you need the dumb pointer you could do this

foo* f = vec[0].get();

I read your update in which you stated

... it seems that the container must indeed be declared to take smart pointers, it can't be made to take either smart or dumb pointers.

You should understand that boost::shared_ptr<Type> is a smart pointer.

like image 30
Rajeshwar Avatar answered Nov 24 '25 20:11

Rajeshwar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!