|
|
|
|
||||||
![]() |
|
|
LinkBack | Outils de la discussion |
|
|
#1 (permalink) |
|
Messages: n/a
Hébergeur: |
I am trying to write a class myVector based on std::vector and add
only a sort method. The sort method needs to access the array stored in the base class using iterator. I have following draft code. However it never compile. Can anyone take a look and tell me how to fix it? Thanks! #include <vector> #include <iostream> using namespace std; template <typename T> class myVector : public vector<T> { public: void Sort(); }; template <typename T> void Sort<T>::Sort() { if (this.size() < 2) { return; } vector<T>::iterator i; for (i = this.begin(); i != this.end(); i++) { //rest part ignored.... } } |
|
|
|
#2 (permalink) |
|
Messages: n/a
Hébergeur: |
On 2007-10-18 09:29, wangxiaohu wrote:
> I am trying to write a class myVector based on std::vector and add > only a sort method. The sort method needs to access the array stored > in the base class using iterator. I have following draft code. However > it never compile. Can anyone take a look and tell me how to fix it? > Thanks! > > #include <vector> > #include <iostream> > > using namespace std; > > template <typename T> class myVector : public vector<T> The general advice is to not inherit from the standard containers, instead create a class that wraps the container. > { > public: > void Sort(); > }; > > template <typename T> void Sort<T>::Sort() template <typename T> void <myVector<T>::sort() > { > if (this.size() < 2) this->size() This is a pointer to the current object, you need to use the dereference operator (->) when accessing members of the current object. -- Erik Wikström |
|
|
|
#3 (permalink) |
|
Messages: n/a
Hébergeur: |
wangxiaohu wrote:
> I am trying to write a class myVector based on std::vector and add > only a sort method. BadIdea(tm). That is abuse of inheritance. You should use a free standing function instead: template < typename T, typename A > void sort_vector ( std::vector<T,A> & sequence ) { std::sort( sequence.begin(), sequence.end() ); } or maybe even more generic: template < typename Container > void sort_sequence ( Container & sequence ) { std::sort( sequence.begin(), sequence.end() ); } or with a concept check: template < typename Container > void sort_sequence ( Container & sequence, typename enable_if < is_sequence< Container >::value, void* >::type = 0 ) { std::sort( sequence.begin(), sequence.end() ); } There are some cases where public inheritance from std::vector<> is justified. This does not look like one of them. > The sort method needs to access the array stored > in the base class using iterator. I have following draft code. However > it never compile. Can anyone take a look and tell me how to fix it? > Thanks! > > #include <vector> > #include <iostream> > > using namespace std; Don't put using directives in header files. Your decision to pull all identifiers from the standard namespace is inflicted upon every user of your class. That is very intrusive. > template <typename T> class myVector : public vector<T> > { > public: > void Sort(); > }; > > template <typename T> void Sort<T>::Sort() Shouldn't that be something like template <typename T> void myVector::Sort() > { > if (this.size() < 2) > { > return; > } > > vector<T>::iterator i; You would need to say typename std::vector<T>::iterator i; The keyword here is "dependent name". > > for (i = this.begin(); i != this.end(); i++) > { > //rest part ignored.... > } > } BTW: why are you doing your own sort algorithm? any why only for vectors? It is _very_ hard to beat std::sort() from the header <algorithm>. Best Kai-Uwe Bux |
|
|
|
#4 (permalink) |
|
Messages: n/a
Hébergeur: |
I just want to see if I can add a Sort() method to the existing vector
container. What you've shown is write a individual function, which does work for the purpose, but does not answer my question. But really thanks to your detailed example! wxh On 10 18 , 1 22 , Kai-Uwe Bux <jkherci...@gmx.net> wrote: > wangxiaohu wrote: > > I am trying to write a class myVector based on std::vector and add > > only a sort method. > > BadIdea(tm). That is abuse of inheritance. You should use a free standing > function instead: > > template < typename T, typename A > > void sort_vector ( std::vector<T,A> & sequence ) { > std::sort( sequence.begin(), sequence.end() ); > } > > or maybe even more generic: > > template < typename Container > > void sort_sequence ( Container & sequence ) { > std::sort( sequence.begin(), sequence.end() ); > } > > or with a concept check: > > template < typename Container > > void sort_sequence > ( Container & sequence, > typename enable_if > < is_sequence< Container >::value, void* >::type = 0 ) { > std::sort( sequence.begin(), sequence.end() ); > } > > There are some cases where public inheritance from std::vector<> is > justified. This does not look like one of them. > > > The sort method needs to access the array stored > > in the base class using iterator. I have following draft code. However > > it never compile. Can anyone take a look and tell me how to fix it? > > Thanks! > > > #include <vector> > > #include <iostream> > > > using namespace std; > > Don't put using directives in header files. Your decision to pull all > identifiers from the standard namespace is inflicted upon every user of > your class. That is very intrusive. > > > template <typename T> class myVector : public vector<T> > > { > > public: > > void Sort(); > > }; > > > template <typename T> void Sort<T>::Sort() > > Shouldn't that be something like > > template <typename T> > void myVector::Sort() > > > { > > if (this.size() < 2) > > { > > return; > > } > > > vector<T>::iterator i; > > You would need to say > > typename std::vector<T>::iterator i; > > The keyword here is "dependent name". > > > > > for (i = this.begin(); i != this.end(); i++) > > { > > //rest part ignored.... > > } > > } > > BTW: why are you doing your own sort algorithm? any why only for vectors? It > is _very_ hard to beat std::sort() from the header <algorithm>. > > Best > > Kai-Uwe Bux |
|
|
|
#5 (permalink) |
|
Messages: n/a
Hébergeur: |
wangxiaohu wrote:
> I just want to see if I can add a Sort() method to the existing vector > container. > > What you've shown is write a individual function, which does work for > the purpose, but does not answer my question. > It appears you asked out of curiosity. Here is one way to do it: template < typename T > class sort_vector : public std::vector< T > { public: sort_vector ( void ) : std::vector< T > () {} template < typename A > sort_vector ( A a ) : std::vector< T > ( a ) {} template < typename A, typename B > sort_vector ( A a, B b ) : std::vector< T > ( a, b ) {} template < typename A, typename B, typename C > sort_vector ( A a, B b, C c ) : std::vector< T > ( a, b, c ) {} template < typename A, typename B, typename C, typename D > sort_vector ( A a, B b, C c, D d ) : std::vector< T > ( a, b, c, d ) {} void sort ( void ) { std::sort( this->begin(), this->end() ); } }; // sort_vector<> Note the templated constructors. They just forward everything to the underlying vector. One of those even allows to convert from std::vector<T> to sort_vector<T>. That mitigates one of the most troublesome drawbacks of public inheritance from standard containers: surprises when used with functions like template < typename T, typename A > std::vector<T,A> reverse_order ( std::vector<T,A> const & ); Note that sort_vector<T> will match the argument type. But the result will not be a sort_vector<T>. > On 10 18 , 1 22 , Kai-Uwe Bux <jkherci...@gmx.net> wrote: >> wangxiaohu wrote: and: please don't top post. It is frowned upon around these parts of the net. See the FAQ for the sentiment about top-posting and other netiquette matters that most regulars of this group share. [snip] Best Kai-Uwe Bux |
|
|
|
#6 (permalink) |
|
Messages: n/a
Hébergeur: |
On Thu, 2007-10-18 at 08:04 +0000, Erik Wikström wrote: > The general advice is to not inherit from the standard containers, > instead create a class that wraps the container. I'd heard that was because somebody might use a reference to your object with type std::vector<...>& and use all the wrong functions. What about private inheritance? Is there any other problem that makes that a bad idea too? It would save the repetitive typing of all the overloads to forward to the implementation if one could just type "using std::vector<...> member;" over and over with different members. -- Tristan Wibberley Any opinion expressed is mine (or else I'm playing devils advocate for the sake of a good argument). My employer had nothing to do with this communication. |
|
|
|
#7 (permalink) |
|
Messages: n/a
Hébergeur: |
On 2007-10-20 16:58:47 -0400, Tristan Wibberley <maihem-nn1@maihem.org> said:
> > On Thu, 2007-10-18 at 08:04 +0000, Erik Wikström wrote: > >> The general advice is to not inherit from the standard containers, >> instead create a class that wraps the container. > > I'd heard that was because somebody might use a reference to your object > with type std::vector<...>& and use all the wrong functions. This doesn't make sense. I thought the whole point of Object-Oriented Programming is that polymophisms are encouraged as a coding structure. If a derived class can potentially ``damaged'' the integrity of the base class, then as the designer of the base class he shouldn't have allowed his methods be declared virtual (so that the derived class could not override it). If so, how then can any reference of the base class be using any wrong methods supplied by the derived class? > > Is there any other problem that makes that a bad idea too? Yea, I like to know too. -- -kira |
|
|
|
#8 (permalink) |
|
Messages: n/a
Hébergeur: |
Tristan Wibberley wrote:
> On Thu, 2007-10-18 at 08:04 +0000, Erik Wikström wrote: > >> The general advice is to not inherit from the standard containers, >> instead create a class that wraps the container. > > I'd heard that was because somebody might use a reference to your object > with type std::vector<...>& and use all the wrong functions. What about > private inheritance? > > Is there any other problem that makes that a bad idea too? > Standard containers don't have virtual destructors. > It would save the repetitive typing of all the overloads to forward to > the implementation if one could just type "using std::vector<...> > member;" over and over with different members. > Rather than extending a container, consider providing a function or operator that operates on one. std::sort would have solved the OP's problem. -- Ian Collins. |
|
![]() |
| Outils de la discussion | |
|
|