Boost logo

Boost Users :

From: Marcel Loose (loose_at_[hidden])
Date: 2003-10-17 06:38:32


Hi,

I have a question related to the boost::shared_ptr constructor.
I want to be able to store boost::shared_ptr<Base> objects in a std::vector. However, I don't want to bother my users with the fact (implementation detail) that I'm using shared_ptrs instead of raw pointers.

The simplified sample code below more or less clarifies what I want. The code in line 27 is the code I would like to be able to use. Below that line, several attempts to get the code to compile can be found. I understand that line 32 won't compile, because it is equivalent to line 27. However, line 37 left me puzzled. I would expect that the conversion of B* to shared_ptr<B> would be trivial. Not so.

Is it really true that the only way to use shared_ptr in the way I want is as in lines 46, 47? Or am I overlooking something? And is line 41 equivalent to line 46?
Thanks in advance.

Regards,

        Marcel Loose.

P.S.: I noticed that all code will compile if I omit the "explicit" keyword in the constructor of shared_ptr, but I don't consider that the proper way to solve the problem.

1:#include <boost/shared_ptr.hpp>
2:#include <vector>
3:
4:using namespace std;
5:using namespace boost;
6:
7:class Base
8:{
9:public:
10: Base() { /* ... */ }
11: virtual ~Base() {}
12:};
13:
14:class Derived : public Base
15:{
16:public:
17: Derived() { /* ... */ }
18: virtual ~Derived() {}
19:};
20:
21:
22:int main()
23:{
24: vector<shared_ptr<Base> > v;
25:
26: { // failes to compile:
27: v.push_back(new Derived()); // cannot convert Derived*&
28: } // to shared_ptr<Base>. Why?
29:
30: { // failes to compile:
31: Derived* d(new Derived()); // cannot convert Derived*&
32: v.push_back(d); // to shared_ptr<Base>. Why?
33: }
34:
35: { // failes to compile:
36: Base* b(new Derived()); // cannot convert Base*&
37: v.push_back(b); // to shared_ptr<Base>. Huh?
38: } // Seems a trivial conversion.
39:
40: { // OK, this compiles, but is
41: shared_ptr<Derived> d(new Derived()); // it correct? I.e. is conversion
42: v.push_back(d); // shared_ptr<Derived> to
43: } // shared_ptr<Base> trivial?
44:
45: { // OK, this compiles, and is
46: shared_ptr<Base> b(new Derived()); // probably what I meant.
47: v.push_back(b); // However, I dislike the
48: } // verbosity.
49:
50: return 0;
51:}

Just to be complete, please find the compiler diagnostics below.

tBoost.cc: In function `int main()':
tBoost.cc:27: no matching function for call to `
   std::vector<boost::shared_ptr<Base>, std::allocator<boost::shared_ptr<Base>
> >::push_back(Derived*&)'
/usr/local/gcc-3.2.1/include/c++/3.2.1/bits/stl_vector.h:490: candidates are:
   void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp =
   boost::shared_ptr<Base>, _Alloc = std::allocator<boost::shared_ptr<Base> >]
tBoost.cc:32: no matching function for call to `
   std::vector<boost::shared_ptr<Base>, std::allocator<boost::shared_ptr<Base>
> >::push_back(Derived*&)'
/usr/local/gcc-3.2.1/include/c++/3.2.1/bits/stl_vector.h:490: candidates are:
   void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp =
   boost::shared_ptr<Base>, _Alloc = std::allocator<boost::shared_ptr<Base> >]
tBoost.cc:37: no matching function for call to `
   std::vector<boost::shared_ptr<Base>, std::allocator<boost::shared_ptr<Base>
> >::push_back(Base*&)'
/usr/local/gcc-3.2.1/include/c++/3.2.1/bits/stl_vector.h:490: candidates are:
   void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp =
   boost::shared_ptr<Base>, _Alloc = std::allocator<boost::shared_ptr<Base> >]
 


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net