boost:shared_ptr cast problem

J

Jun

Hello,

I've code like :
===========================================
class A{
public :
// create print content
friend std::eek:stream& operator<< (std::eek:stream&
os, const A& a);

}

typedef boost::shared_ptr<A> APtr; // Define A class smart pointer

APtr aPtr1(new A());
APtr aPtr2(new A());
APtr aPtr3(new A());

vector<APtr> AVec;
AVec.push_back(aPtr1);
AVec.push_back(aPtr2);
AVec.push_back(aPtr3);

std::copy(AVec.begin(),AVec.end(),
std::eek:stream_iterator<APtr>(std::cout, "\n"));

(std::cout, "\n"));
===========================================

The two copy methods only output the address of pointers, they could
just print the class A defined print contents. And following code
works :
===========================================
vector<APtr>::iterator i = AVec.begin();
for(; i!= AVec.end(); ++i){
cout << *static_cast<APtr>(*i) << endl;
}
===========================================

Anyone has some ideas for that ? Thank you in advance.


Jun
 
J

Jun

Hello,

I've code like :
===========================================
class A{
public :
// create print content
friend std::eek:stream& operator<< (std::eek:stream&
os, const A& a);

}

typedef boost::shared_ptr<A> APtr; // Define A class smart pointer

APtr aPtr1(new A());
APtr aPtr2(new A());
APtr aPtr3(new A());

vector<APtr> AVec;
AVec.push_back(aPtr1);
AVec.push_back(aPtr2);
AVec.push_back(aPtr3);

std::copy(AVec.begin(),AVec.end(),
std::eek:stream_iterator<APtr>(std::cout, "\n"));

std::copy(AVec.begin(),AVec.end(), std::eek:stream_iterator< share_ptr<A>>(std::cout, "\n"));

===========================================

The two copy methods only output the address of pointers, they could
just print the class A defined print contents. And following code
works :
===========================================
vector<APtr>::iterator i = AVec.begin();
for(; i!= AVec.end(); ++i){
cout << *static_cast<APtr>(*i) << endl;
}
===========================================

Anyone has some ideas for that ? Thank you in advance.

Jun

Actually, It's boost::shared_ptr serialization problem.
 
K

Kai-Uwe Bux

Jun said:
Hello,

I've code like :
===========================================
class A{
public :
// create print content
friend std::eek:stream& operator<< (std::eek:stream&
os, const A& a);

}

typedef boost::shared_ptr<A> APtr; // Define A class smart pointer

APtr aPtr1(new A());
APtr aPtr2(new A());
APtr aPtr3(new A());

vector<APtr> AVec;
AVec.push_back(aPtr1);
AVec.push_back(aPtr2);
AVec.push_back(aPtr3);

std::copy(AVec.begin(),AVec.end(),
std::eek:stream_iterator<APtr>(std::cout, "\n"));

std::copy(AVec.begin(),AVec.end(),
std::eek:stream_iterator< share_ptr<A> >(std::cout, "\n"));
===========================================

The two copy methods only output the address of pointers, they could
just print the class A defined print contents.

Why would you expect that? Consider

int i = 5;
std::cout << i << std::endl
<< &i << std::endl;

You would expect the second line to print an address, would you not? Why
should shared_ptr<> behave differently? Also note that shared_ptr could
have null value. In that case, there is no pointee that could be printed
instead of an address.

And following code works :
===========================================
vector<APtr>::iterator i = AVec.begin();
for(; i!= AVec.end(); ++i){
cout << *static_cast<APtr>(*i) << endl;
}
===========================================
Anyone has some ideas for that ?

Yes, leave out the cast: *i is already of type APtr.

cout << *(*i) << endl;



BTW: I have the feeling that I did not really understand what the real
problem is that you want to solve. Maybe, you oversimplified it for the
purpose of the post. Could you provide a little background as to _why_ you
want to print the shared_ptr and _why_ you feel it would be the
RightThing(tm) if that printed the pointee instead of an address? Maybe, it
is the context of the underlying problem that makes you think printing the
pointee would be right. In that case, it would be good to share the
underlying problem with us, because it might have a well known solution.


Best

Kai-Uwe Bux
 
J

Jun

Why would you expect that? Consider

int i = 5;
std::cout << i << std::endl
<< &i << std::endl;

You would expect the second line to print an address, would you not? Why
should shared_ptr<> behave differently? Also note that shared_ptr could
have null value. In that case, there is no pointee that could be printed
instead of an address.


Yes, leave out the cast: *i is already of type APtr.

cout << *(*i) << endl;

BTW: I have the feeling that I did not really understand what the real
problem is that you want to solve. Maybe, you oversimplified it for the
purpose of the post. Could you provide a little background as to _why_ you
want to print the shared_ptr and _why_ you feel it would be the
RightThing(tm) if that printed the pointee instead of an address? Maybe, it
is the context of the underlying problem that makes you think printing the
pointee would be right. In that case, it would be good to share the
underlying problem with us, because it might have a well known solution.

Best

Kai-Uwe Bux

I've a person class, which contains name, age. I applied output as
name age,
for my custom class. By storing it as a smart pointer PersonPtr in a
vector.
Then my idea is using copy algorithm to print out all the PersonPtr in
the
vector, but failed. Since PersonPtr has the serialization problem. By
using
copy algorithm, it only prints the address of smart pointer instead
name age,
which i defined.
 
K

Kai-Uwe Bux

Jun said:
I've a person class, which contains name, age. I applied output as
name age,
for my custom class. By storing it as a smart pointer PersonPtr in a
vector.
Then my idea is using copy algorithm to print out all the PersonPtr in
the
vector, but failed. Since PersonPtr has the serialization problem. By
using
copy algorithm, it only prints the address of smart pointer instead
name age,
which i defined.

You might try:

template < typename T >
T const & deref ( std::tr1::shared_ptr<T> ptr ) {
return ( *ptr );
}

and

std::transform( AVec.begin(), AVec.end(),
std::eek:stream_iterator< A >( std::cout, "\n" ),
&deref<A> );

Maybe, there is a way to use boost::lambda and just say

std::transform( AVec.begin(), AVec.end(),
std::eek:stream_iterator< A >( std::cout, "\n" ),
*_1);

without the need to define deref.


Best

Kai-Uwe Bux
 
J

Jun

You might try:

template < typename T >
T const & deref ( std::tr1::shared_ptr<T> ptr ) {
return ( *ptr );

}

and

std::transform( AVec.begin(), AVec.end(),
std::eek:stream_iterator< A >( std::cout, "\n" ),
&deref<A> );

Maybe, there is a way to use boost::lambda and just say

std::transform( AVec.begin(), AVec.end(),
std::eek:stream_iterator< A >( std::cout, "\n" ),
*_1);

without the need to define deref.

Best

Kai-Uwe Bux

I saw the lambda solution, anyway, I will try and post the results.
Jun
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,173
Messages
2,570,938
Members
47,473
Latest member
pioneertraining

Latest Threads

Top