 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
NemraŽ Guest
|
Posted: Thu Oct 20, 2005 2:45 am Post subject: Redundant copy ctr calls |
|
|
Object construction in standard C++ library has some specifics. Lets
discuss one of them: consider you have class T with simplest default
ctr (just initializes to 0 most of members) and copy ctr, which have to
make lots of checking in order to provide safe resource management
(std::string can be one of examples). Now consider using
std::vector<T> vec;
The simplest resize(N) should create K = (N - vec.size()) new elements
if N is bigger than vec.size(). Let's ignore possible re-allocation of
the memory and copy of the old elements. Instead of calling default ctr
K times, the copy ctr will be called because of allocator interface
requirement.
What if allocator will have another version of construct()?
class allocator // interface definition
{
void construct(pointer p, const T& v); // uses the copy
void construct(pointer p); // uses default ctr
};
Standard doesn't require default ctr, which might be useful for
std::set and std::map (if T is used as key only), but other containers
require default ctr anyway. Actually std::vector is used heavily in
applications more than others (just my experience), so having its
optimized implementation is preferable (for example now most
implementations use fast copy when working with PODs, which makes
unnecessary writing separate vector version for that by developers,
which is GOOD).
What do you think?
Regards,
Armen
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
Carl Barron Guest
|
Posted: Thu Oct 20, 2005 1:55 pm Post subject: Re: Redundant copy ctr calls |
|
|
In article <1129710455.248221.54730 (AT) g44g2000cwa (DOT) googlegroups.com>,
NemraŽ <armen_grigoryan (AT) hotmail (DOT) com> wrote:
| Quote: | Object construction in standard C++ library has some specifics. Lets
discuss one of them: consider you have class T with simplest default
ctr (just initializes to 0 most of members) and copy ctr, which have to
make lots of checking in order to provide safe resource management
(std::string can be one of examples). Now consider using
std::vector<T> vec;
The simplest resize(N) should create K = (N - vec.size()) new elements
if N is bigger than vec.size(). Let's ignore possible re-allocation of
the memory and copy of the old elements. Instead of calling default ctr
K times, the copy ctr will be called because of allocator interface
requirement.
What if allocator will have another version of construct()?
class allocator // interface definition
{
void construct(pointer p, const T& v); // uses the copy
void construct(pointer p); // uses default ctr
};
Standard doesn't require default ctr, which might be useful for
std::set and std::map (if T is used as key only), but other containers
require default ctr anyway. Actually std::vector is used heavily in
applications more than others (just my experience), so having its
optimized implementation is preferable (for example now most
implementations use fast copy when working with PODs, which makes
unnecessary writing separate vector version for that by developers,
which is GOOD).
What do you think?
Why modify the standard library when the following are probably true |
a compilcated object should not be unnecessarily copied [use a smart
ptr for instance] and boost [www.boost.org] has two header only
libraries smart pointer and iterator that make life fairly simple.
using boost::shared_ptr or boost::intrusive_ptr you can safely store
pointers in the containers as intrusive_ptr's or shared_ptr's, and use
boost::indirect_iterator to access the contents of the container as if
they were objects of type T instead of boost::shared_ptr<T>or
boost::intrusive_ptr<T>.
using boost::shared_ptr<T> requires no modifications to T but has
a larger footprint than intrusive_ptr and more memory allocations
for an instance of shared_ptr<T> than intrusive_ptr<T> does.
But intrusive_ptr<T> as the name implies is intrusive and requires
modification of T to contain a reference count, access that count,
and contructors/asignment operators of T set that count to zero.
example
std::vector<boost::shared_ptr container;
void do_something(T &);
template <class C>
void do_all(C &c)
{
std::for_each
(
boost::make_indirect_iterator(c.begin()),
boost::make_indirect_iterator(c.end()),
do_something
);
}
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
chris jefferson Guest
|
Posted: Thu Oct 20, 2005 1:59 pm Post subject: Re: Redundant copy ctr calls |
|
|
NemraŽ wrote:
| Quote: | Object construction in standard C++ library has some specifics. Lets
discuss one of them: consider you have class T with simplest default
ctr (just initializes to 0 most of members) and copy ctr, which have to
make lots of checking in order to provide safe resource management
(std::string can be one of examples). Now consider using
std::vector<T> vec;
The simplest resize(N) should create K = (N - vec.size()) new elements
if N is bigger than vec.size(). Let's ignore possible re-allocation of
the memory and copy of the old elements. Instead of calling default ctr
K times, the copy ctr will be called because of allocator interface
requirement.
What if allocator will have another version of construct()?
class allocator // interface definition
{
void construct(pointer p, const T& v); // uses the copy
void construct(pointer p); // uses default ctr
};
This would indeed be a sensible idea, I personally would have thought |
this would have been done from the start, rather than saving a tiny bit
of time having an optional parameter.
This is actually already in the pipeline to be changed when move
semantics get introduced, exactly to avoid the requirement that types
are copyable.
Chris
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
NemraŽ Guest
|
Posted: Sat Oct 22, 2005 1:50 pm Post subject: Re: Redundant copy ctr calls |
|
|
The point is that object doesn't have to be complicated. It might be
simple, but anyway its copy constructor call in this case is
unnecessary. Even copying smart pointers like shared_ptr requires some
actions which in fact are not necessary.
About complex objects: for example having smart pointers to strings and
allocating strings for keeping in container is not a nice solution,
IMHO.
Regards,
Armen
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|