smart ptrs in vectors

E

er

hi,

i'm wondering what is the role of A::eek:perator= below in doing:
Impl impl0(0);
A a0(impl0);
std::vector<A> vec;
vec.push_back(a0);

if i put it as private the compiler complains but if i put it as
public, the message "A::eek:perator=" does not appear. the message
"A::A(A&)" however does print. any suggestion appreciated. thanks!

class Impl{
public:
Impl(unsigned int i_):i(i_){};
private:
unsigned int i;
};
class A{
public:
A(Impl& impl_):impl(impl_){};
A(const A& a):impl(a.impl){std::cout<<"A::A(const
A&)"<<std::endl;};
A& operator=(const A& a);
A& operator=(const A& a);{//complain if private
std::cout<<"A::eek:perator="<<std::endl;//does not show
if(&a!=this){
throw
std::runtime_error("A::eek:perator=");
};
return *this;
};
private:
A();
Impl& impl;//Impl& instead of some_ptr<Impl> because i intend to
keep impl throughout lifetime of A. anything wrong with it?
};
 
E

er

hi,

i'm wondering what is the role of A::eek:perator= below in doing:
Impl impl0(0);
A a0(impl0);
std::vector<A> vec;
vec.push_back(a0);

if i put it as private the compiler complains but if i put it as
public, the message "A::eek:perator=" does not appear. the message
"A::A(A&)" however does print. any suggestion appreciated. thanks!

class Impl{
public:
Impl(unsigned int i_):i(i_){};
private:
unsigned int i;};

class A{
public:
A(Impl& impl_):impl(impl_){};
A(const A& a):impl(a.impl){std::cout<<"A::A(const
A&)"<<std::endl;};
A& operator=(const A& a);
A& operator=(const A& a);{//complain if private
std::cout<<"A::eek:perator="<<std::endl;//does not show
if(&a!=this){
throw
std::runtime_error("A::eek:perator=");
};
return *this;
};
private:
A();
Impl& impl;//Impl& instead of some_ptr<Impl> because i intend to
keep impl throughout lifetime of A. anything wrong with it?

};

ps: ignore the first A& operator=(const A& a)
 
B

Barry

er said:
hi,

i'm wondering what is the role of A::eek:perator= below in doing:
Impl impl0(0);
A a0(impl0);
std::vector<A> vec;
vec.push_back(a0);

if i put it as private the compiler complains but if i put it as
public, the message "A::eek:perator=" does not appear. the message
"A::A(A&)" however does print. any suggestion appreciated. thanks!

I guess that's specific implementation like VC,
And I guess it use placement new to copy the new 'push_back'ed element,
that's why copy ctor is called.

Though not using A::eek:perator=, but STL require element of container to
be Assignable, so I also guess it borrow some concept check.

All my guess.
class Impl{
public:
Impl(unsigned int i_):i(i_){};
private:
unsigned int i;
};
class A{
public:
A(Impl& impl_):impl(impl_){};
A(const A& a):impl(a.impl){std::cout<<"A::A(const
A&)"<<std::endl;};
A& operator=(const A& a);
A& operator=(const A& a);{//complain if private
std::cout<<"A::eek:perator="<<std::endl;//does not show
if(&a!=this){
throw
std::runtime_error("A::eek:perator=");
};
return *this;
};
private:
A();
Impl& impl;//Impl& instead of some_ptr<Impl> because i intend to
keep impl throughout lifetime of A. anything wrong with it?

Using *Pimpl* idiom (I think you attempt to use it), it's more
straightforward to use pointer, as you don't initialize to the value
(you don't even know what kind of impl to attach); Using pimpl is always
trying to hide implementation, so you use forward declaration for *impl*
rather than a definition of 'impl'.

using reference you have to initialize the reference when you initialize
your 'obj' who wraps it. So you have to garantee the lifetime of the
'impl', which have to live longer than your 'obj'.

So the idiom is *P*ointer *Impl*ementation.
 
J

James Kanze

i'm wondering what is the role of A::eek:perator= below in doing:
Impl impl0(0);
A a0(impl0);
std::vector<A> vec;
vec.push_back(a0);
if i put it as private the compiler complains but if i put it as
public, the message "A::eek:perator=" does not appear. the message
"A::A(A&)" however does print.

The standard says that any object put into a standard container
must be assignable. That doesn't mean that the assignment
operator will be called for all operations on the container.

In this case, what is probably happening is that the
implementation of vector<>::push_back calls vector<>::insert.
And in certain cases (but never when inserting at the end),
insert must use the assignment operator. The reason you get the
compiler error is because the compiler is instantiating a
function which uses it. The reason you never see its output is
because it is in an if/else branch which never actually gets
executed.

Note that some implementations of the library use concept
checking, and you may get an error from the compiler any time
you instantiate the template, e.g. in the declaration, even if
you never actually do anything with the resulting instantiation.
any suggestion appreciated.

Provide a working assignment operator for all objects which are
to be in a standard container.
 
R

Ron Natalie

James said:
The standard says that any object put into a standard container
must be assignable. That doesn't mean that the assignment
operator will be called for all operations on the container.
Yes and the standard also says the objects must be copy constructable.
The copy constructor obviously is what is moving the object into the
container.
 
E

er

Yes and the standard also says the objects must be copy constructable.
The copy constructor obviously is what is moving the object into the
container.

thank you all. it now makes sense. yes i'm aware this is a kind of
pimpl that uses a reference instead of a ptr (i call it rimpl), but
with the benefit your suggestions, it's probably safer to use a ptr.
 

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
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top