473,386 Members | 1,803 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

partial specialization on std::vector

i want to create a vector of pointer s.t. it can handle new and delete
but also have std::vector interface

can i implement by partial specialization and inherence like follow ?

#include <vector>
#include <algorithm>

template <typename T>
struct delete_ptr {
void operator() (T * p) {
delete p;
}
};

template<typename T>
class auto_vector<T *: public std::vector<T *{
public:
typedef std::vector<T *Base;
~auto_vector() {
clear();
}

void clear() {
std::for_each(begin(), end(), delete_ptr<T>());
Base::clear();
}

void push_back(const T *p) {
T* tmp = new T(*p)
Base::push_back(tmp);
}
};

Oct 29 '06 #1
6 3220
<lo*****@gmail.comwrote in message
news:11**********************@b28g2000cwb.googlegr oups.com
i want to create a vector of pointer s.t. it can handle new and delete
but also have std::vector interface

can i implement by partial specialization and inherence like follow ?

#include <vector>
#include <algorithm>

template <typename T>
struct delete_ptr {
void operator() (T * p) {
delete p;
}
};

template<typename T>
class auto_vector<T *: public std::vector<T *{
public:
typedef std::vector<T *Base;
~auto_vector() {
clear();
}

void clear() {
std::for_each(begin(), end(), delete_ptr<T>());
Base::clear();
}

void push_back(const T *p) {
T* tmp = new T(*p)
Base::push_back(tmp);
}
};
I suggest you might like to look at the Boost Pointer Containers:

http://www.boost.org/libs/ptr_contai...container.html
--
John Carson
Oct 29 '06 #2

lo*****@gmail.com wrote:
i want to create a vector of pointer s.t. it can handle new and delete
but also have std::vector interface

can i implement by partial specialization and inherence like follow ?

#include <vector>
#include <algorithm>

template <typename T>
struct delete_ptr {
void operator() (T * p) {
delete p;
}
};

template<typename T>
class auto_vector<T *: public std::vector<T *{
public:
typedef std::vector<T *Base;
~auto_vector() {
clear();
}

void clear() {
std::for_each(begin(), end(), delete_ptr<T>());
Base::clear();
}

void push_back(const T *p) {
T* tmp = new T(*p)
Base::push_back(tmp);
}
};
The stl containers are not designed to be inherited from ( no virtual
destructors ).
Besides, the container you are trying to code is_not a std::vector, it
looks like a std::vector.
What if someone copies that container?
What if the template parameter is a pointer?
I'ld suggest smart pointers as a better alternative to raw allocations.

#include <iostream>
#include <ostream>
#include <vector>
#include <boost/shared_ptr.hpp>

template< typename T >
class auto_vector
{
typedef boost::shared_ptr< T SharedPtrT;
std::vector< SharedPtrT m_vp;
typedef typename std::vector< SharedPtrT >::const_iterator VCIter;
public:
/* ctors */
auto_vector() : m_vp() { }
auto_vector(const auto_vector& r_copy)
{
for(VCIter viter = r_copy.m_vp.begin();
viter != r_copy.m_vp.end(); ++viter)
{
m_vp.push_back( SharedPtrT( new T(*(*viter)) ) );
}
}
/* member functions */
void push_back( const T& t )
{
m_vp.push_back( SharedPtrT( new T(t) ) );
}
void clear()
{
m_vp.clear();
}
/* friends */
friend
std::ostream&
operator<<( std::ostream& os, const auto_vector& r_av )
{
for(VCIter viter = r_av.m_vp.begin();
viter != r_av.m_vp.end(); ++viter)
{
os << *(*viter) << "\n";
}
return os;
}
};

int main()
{
auto_vector< int avn;
for( int i = 0; i < 2; ++i)
{
avn.push_back( i );
}
std::cout << avn << std::endl;

return 0;
}

and the ouput using a simple struct instead of int:
N(int) // temp
N(const N& copy) // push_back
~N() // temp
N(int) // temp
N(const N& copy) // push_back
~N() // temp
0
1
~N()
~N()

Oct 29 '06 #3
Salt_Peter wrote:
....
The stl containers are not designed to be inherited from ( no virtual
destructors ).
All your other suggestions aside. I think the consensus is that "no
virtual destructor" is not a reason for "not being designed" to be
inherited.

A virtual destructor is only needed if you destroy your object from a
super class. Most people agree that that usually means if you have any
virtual methods - but not necessarily so. For example, I just posted
code on a different thread where objects are created statically yet they
have virtual methods.

It is perfectly ok to inherit from std::vector and yes there are
limitations but if those limitations are not an issue, the world is good.
Oct 29 '06 #4
lo*****@gmail.com wrote:
i want to create a vector of pointer s.t. it can handle new and delete
but also have std::vector interface

can i implement by partial specialization and inherence like follow ?

#include <vector>
#include <algorithm>

template <typename T>
struct delete_ptr {
void operator() (T * p) {
delete p;
}
};

template<typename T>
class auto_vector<T *: public std::vector<T *{
public:
typedef std::vector<T *Base;
~auto_vector() {
clear();
}

void clear() {
std::for_each(begin(), end(), delete_ptr<T>());
Base::clear();
}

void push_back(const T *p) {
T* tmp = new T(*p)
Base::push_back(tmp);
}
};
This is a strange design:

a) the vector goes through some length to make copies in the push_back
method, however allows for ordinary access through operaror=. This is quite
inconsistent.

b) When the copy constructor of the vector is used, the result will be two
vectors both owning the pointers. When the first vector is destroyed, the
second becomes invalid and any call to its destructor becomes undefined
behavior.

c) The way the push_back method is implemented, it does not support
polymorphic pointers:

T* tmp = new T (*p);

will slice should p actually point to an object of type derived from T.
What problem are you trying to solve? Why do you want a vector of pointers
and not of objects in the first place: if it is to support polymorphism,
but you want to preserve copy semantics for the container, then you might
want to look into smart-pointers with copy semantics. Several have been
posted in this group; some of them also define comparison in terms of the
pointees. Then, you could just use std::vector< copy_ptr<T and even sort
would do the RightThing(tm). Google for copy_ptr<or clone_ptr<in the
archive of this group and its moderated twin.
Best

Kai-Uwe Bux
Oct 29 '06 #5

Gianni Mariani wrote:
Salt_Peter wrote:
...
The stl containers are not designed to be inherited from ( no virtual
destructors ).

All your other suggestions aside. I think the consensus is that "no
virtual destructor" is not a reason for "not being designed" to be
inherited.

A virtual destructor is only needed if you destroy your object from a
super class. Most people agree that that usually means if you have any
virtual methods - but not necessarily so. For example, I just posted
code on a different thread where objects are created statically yet they
have virtual methods.

It is perfectly ok to inherit from std::vector and yes there are
limitations but if those limitations are not an issue, the world is good.
Its not the lack of the virtual destructor alone that should discourage
inheriting from a container like the std::vector in a case like this
one. In fact its a secondary issue. Perhaps i should have made a
cleaner point of it.

Public inheritance forces the coder to override the entire interface
(operator[], assignment, at(), etc). What happens if an unsuspecting
user of the code tries to iterate through the elements, which are
actually pointers? What if one attempts to presize the container using
a vector's ctor? What if a common algorithm (swap, count_if, replace,
remove_if, sort, min, nth_element, etc) is applied to the container?
And so on.
Clearly, its no longer a std::vector, is it?

Oct 29 '06 #6
Salt_Peter wrote:
>
Gianni Mariani wrote:
>Salt_Peter wrote:
...
The stl containers are not designed to be inherited from ( no virtual
destructors ).

All your other suggestions aside. I think the consensus is that "no
virtual destructor" is not a reason for "not being designed" to be
inherited.

A virtual destructor is only needed if you destroy your object from a
super class. Most people agree that that usually means if you have any
virtual methods - but not necessarily so. For example, I just posted
code on a different thread where objects are created statically yet they
have virtual methods.

It is perfectly ok to inherit from std::vector and yes there are
limitations but if those limitations are not an issue, the world is good.

Its not the lack of the virtual destructor alone that should discourage
inheriting from a container like the std::vector in a case like this
one. In fact its a secondary issue. Perhaps i should have made a
cleaner point of it.

Public inheritance forces the coder to override the entire interface
(operator[], assignment, at(), etc).
Using public innheritance, only the parts that need to be changed in order
to ensure the proper semantics need to be overwritten. Unfortunately, if
the OP wants deep-copy-semantics for the vector entries, as indicated by
his implementation of the push_back() method, this would entail
reimplementing the entire iterator type. I conclude, you have a valid point
here. However, this effort is not a consequence of public inheritance: all
other methods will not safe any work.

What happens if an unsuspecting
user of the code tries to iterate through the elements, which are
actually pointers?
The user should get a compile time error.
What if one attempts to presize the container using
a vector's ctor?
Huh? Could you provide a code snippet: I do not quite understand what you
have in mind.
What if a common algorithm (swap, count_if, replace,
remove_if, sort, min, nth_element, etc) is applied to the container?
And so on.
Clearly, its no longer a std::vector, is it?
Of course it *is* a std::vector. However, it is not a std::vector<Tbut a
std::vector<T*>. The OP said he wanted a vector of pointers. He proposed:

template<typename T>
class auto_vector<T *: public std::vector<T *{
public:
...
};

To answer your what-if questions: std::sort will sort it happily using
less<T*>, remove_if() could be used to eliminate 0-pointers, and so on.
Since the OP explicitly stated he wants a vector of pointers, this might
even be what he expects. Also, it clearly is consistent with what
std::vector<T*would do. Thus, auto_vector is a std::vector<T*>.
Now, whether a vector of pointers is a good thing to use, is a different
matter.
Best

Kai-Uwe Bux
Oct 29 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

27
by: Jason Heyes | last post by:
To my understanding, std::vector does not use reference counting to avoid the overhead of copying and initialisation. Where can I get a reference counted implementation of std::vector? Thanks.
18
by: Janina Kramer | last post by:
hi ng, i'm working on a multiplayer game for a variable number of players and on the client side, i'm using a std::vector<CPlayer> to store informatik about the players. CPlayer is a class that...
20
by: Anonymous | last post by:
Is there a non-brute force method of doing this? transform() looked likely but had no predefined function object. std::vector<double> src; std::vector<int> dest; ...
17
by: Michael Hopkins | last post by:
Hi all I want to create a std::vector that goes from 1 to n instead of 0 to n-1. The only change this will have is in loops and when the vector returns positions of elements etc. I am calling...
8
by: Ross A. Finlayson | last post by:
I'm trying to write some C code, but I want to use C++'s std::vector. Indeed, if the code is compiled as C++, I want the container to actually be std::vector, in this case of a collection of value...
32
by: zl2k | last post by:
hi, c++ user Suppose I constructed a large array and put it in the std::vector in a function and now I want to return it back to where the function is called. I can do like this: ...
56
by: Peter Olcott | last post by:
I am trying to refer to the same std::vector in a class by two different names, I tried a union, and I tried a reference, I can't seem to get the syntax right. Can anyone please help? Thanks
9
by: aaragon | last post by:
I am trying to create a vector of type T and everything goes fine until I try to iterate over it. For some reason, the compiler gives me an error when I declare std::vector<T>::iterator iter;...
13
by: jubelbrus | last post by:
Hi I'm trying to do the following. #include <vector> #include <boost/thread/mutex.hpp> #include <boost/shared_ptr.hpp> #include <boost/tuple/tuple.hpp> class {
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.