By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
443,889 Members | 1,297 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 443,889 IT Pros & Developers. It's quick & easy.

STL extension

P: n/a
Hello.

I try to extend STL, for example, add member function like trim_left to
basic_string<charT, traits, Alloc>. However I am in the despair as soon as I
see
STL source. I am using STLport 5.0-0409 with vc 6.0.

How can I extend STL easily? Any help will be appreciated. Thanks.
Jul 22 '05 #1
Share this Question
Share on Google+
13 Replies


P: n/a
"Park Ho-Kyung" <il****@eoneo.co.kr> wrote in message
news:cf**********@news1.kornet.net...
Hello.

I try to extend STL, for example, add member function like trim_left to
basic_string<charT, traits, Alloc>. However I am in the despair as soon as I see
STL source. I am using STLport 5.0-0409 with vc 6.0.

How can I extend STL easily? Any help will be appreciated. Thanks.


If you want a trim_left function that operates on a std::string, then you
should implement it as a non-member function. The standard container
classes were not designed for inheritance. There is no reason to extend a
container class to add member functions because that provides no significant
benefits over the non-member function approach. Assuming that you wish to
remove some characters from the string, you could implement it like so:

// returns the result
std::string trim_left( const std::string& s );

// or

// modifies the argument
void trim_left( std::string& s );

You could place this function in a namespace if you don't want it to be in
the global namespace.

--
David Hilsee
Jul 22 '05 #2

P: n/a
Ian
Park Ho-Kyung wrote:
Hello.

I try to extend STL, for example, add member function like trim_left to
basic_string<charT, traits, Alloc>. However I am in the despair as soon as I
see
STL source. I am using STLport 5.0-0409 with vc 6.0.

How can I extend STL easily? Any help will be appreciated. Thanks.

Derive your own classes form those in the STL and add your new
functionality. Don't mess with what's there, that's not the C++ way!

Ian
Jul 22 '05 #3

P: n/a
> The standard container classes were not designed for inheritance.

How not?
There is no reason to extend a container class to add member functions
because that provides no significant benefits over the non-member
function approach.


Other than semantically. IMO, it's a lot more logical to write
str.trim_left() than trim_left(str).

--
Kevin W :-)
Opera/CSS/webdev blog: http://www.exclipy.com/
Using Opera: http://www.opera.com/m2/
Jul 22 '05 #4

P: n/a
"Kevin W." wrote:
The standard container classes were not designed for inheritance.
How not?


Since the said classes have non-virtual destructors, it is immoral to
inherit from them publicly (this has been beaten to death). It may
be a convenient thing to do, but you'd better keep it low, because
a class so derived would not be safe for general-purpose use.
Also, if you tried to preserve all of the base class functionality,
you would have to redefine the constructors (they are plentiful).

There is nothing fundamentally wrong in inheriting from standard
container classes privately. However, there is no advantage in doing
so either (the protected parts, if usable, are undocumented and
library-specific; there are no virtual functions to override, etc.).
Containment would be a better option.

There is no reason to extend a container class to add member functions
because that provides no significant benefits over the non-member
function approach.


Other than semantically. IMO, it's a lot more logical to write
str.trim_left() than trim_left(str).


It's arguable on both sides. This and other operations can be implemented
in terms of a minimal public interface of a corresponding container class.
Some of these operations could be made generic in respect to the container
type.

Denis
Jul 22 '05 #5

P: n/a
Denis Remezov wrote:
"Kevin W." wrote:
> The standard container classes were not designed for inheritance.
How not?


Since the said classes have non-virtual destructors, it is immoral to
inherit from them publicly (this has been beaten to death). It may
be a convenient thing to do, but you'd better keep it low, because
a class so derived would not be safe for general-purpose use.


So then, what about inheriting from a patched string class:
#include <string>

class inheritable_string : public std::string {
public:

inheritable_string ( void ) :
std::string ()
{}

template < typename A >
inheritable_string ( A a ) :
std::string ( a )
{}

template < typename A, typename B >
inheritable_string ( A a, B b ) :
std::string ( a, b )
{}

template < typename A, typename B, typename C >
inheritable_string ( A a, B b, C c ) :
std::string ( a, b, c )
{}

template < typename A, typename B, typename C,
typename D >
inheritable_string ( A a, B b, C c, D d ) :
std::string ( a, b, c, d )
{}

template < typename A, typename B, typename C,
typename D, typename E >
inheritable_string ( A a, B b, C c, D d, E e ) :
std::string ( a, b, c, d, e )
{}

template < typename A, typename B, typename C,
typename D, typename E, typename F >
inheritable_string ( A a, B b, C c, D d, E e, F f ) :
std::string ( a, b, c, d, e, f )
{}

virtual ~inheritable_string ( void ) {}

};

Would it be safe to inherit from here.

Also, if you tried to preserve all of the base class functionality,
you would have to redefine the constructors (they are plentiful).


Is something wrong with the use of templated constructors?

Best

Kai-Uwe Bux
Jul 22 '05 #6

P: n/a
"Kai-Uwe Bux" <jk********@gmx.net> wrote in message
news:cf**********@news01.cit.cornell.edu...
Denis Remezov wrote:
"Kevin W." wrote:

> The standard container classes were not designed for inheritance.

How not?


Since the said classes have non-virtual destructors, it is immoral to
inherit from them publicly (this has been beaten to death). It may
be a convenient thing to do, but you'd better keep it low, because
a class so derived would not be safe for general-purpose use.


So then, what about inheriting from a patched string class:
#include <string>

class inheritable_string : public std::string {
public:

inheritable_string ( void ) :
std::string ()
{}

template < typename A >
inheritable_string ( A a ) :
std::string ( a )
{}

template < typename A, typename B >
inheritable_string ( A a, B b ) :
std::string ( a, b )
{}

template < typename A, typename B, typename C >
inheritable_string ( A a, B b, C c ) :
std::string ( a, b, c )
{}

template < typename A, typename B, typename C,
typename D >
inheritable_string ( A a, B b, C c, D d ) :
std::string ( a, b, c, d )
{}

template < typename A, typename B, typename C,
typename D, typename E >
inheritable_string ( A a, B b, C c, D d, E e ) :
std::string ( a, b, c, d, e )
{}

template < typename A, typename B, typename C,
typename D, typename E, typename F >
inheritable_string ( A a, B b, C c, D d, E e, F f ) :
std::string ( a, b, c, d, e, f )
{}

virtual ~inheritable_string ( void ) {}

};

Would it be safe to inherit from here.


No, the std::string is still exposed.

std::string * p = new inheritable_string();
delete p; // this is a problem

However, the whole virtual destructor issue, to me, is secondary to the fact
that a public inheritance from std::string (or any other standard container)
is, from a design standpoint, about the same as exposing that base class as
a public member. That is, there's not a whole lot of difference between the
following two classes, aside from the need to write "foo.str" instead of
"foo" to access the std::string.

class foo : public std::string {};
class foo {
public:
std::string str; // foo has same benefits as before
};

--
David Hilsee
Jul 22 '05 #7

P: n/a

"Park Ho-Kyung" <il****@eoneo.co.kr> wrote in message
news:cf**********@news1.kornet.net...
Hello.

I try to extend STL, for example, add member function like trim_left to
basic_string<charT, traits, Alloc>. However I am in the despair as soon as I see


save yourself the trouble, wait a week or two, then see the string algorithm
library at www.boost.org. The string algorithm library will be in version
1.32, or follow the directions at the website to get access to the CVS
version.

Jeff F
Jul 22 '05 #8

P: n/a
"Kevin W." <co*****@in.sig> wrote in message
news:op**************@localhost.localdomain...
The standard container classes were not designed for inheritance.


How not?


As Denis pointed out, it has no virtual functions (including the important
destructor) and no protected members. Derived classes get no extra
benefits.
There is no reason to extend a container class to add member functions
because that provides no significant benefits over the non-member
function approach.


Other than semantically. IMO, it's a lot more logical to write
str.trim_left() than trim_left(str).


Logical, or pretty? Lots of the functions in the C++ library are not member
functions (e.g. sin(), sort()), and, for the most part, they don't seem any
more or less logical than the member functions.

--
David Hilsee
Jul 22 '05 #9

P: n/a


Kevin W. wrote:


Other than semantically. IMO, it's a lot more logical to write
str.trim_left() than trim_left(str).


Actually it probably isn't:
http://www.cuj.com/documents/s=8042/cuj0002meyers/

"In 1998, however, I gave a presentation at Actel, where Arun Kundu
observed that my algorithm dictated that functions should be member
functions even when they could be implemented as non-members that
used only C's public interface. Is that really what I meant, he asked
me? In other words, if f could be implemented as a member function or
a non-friend non-member function, did I really advocate making it a
member function? I thought about it for a moment, and I decided that
that was not what I meant."

Jul 22 '05 #10

P: n/a
Park Ho-Kyung wrote:

Hello.

I try to extend STL, for example, add member function like trim_left to
basic_string<charT, traits, Alloc>. However I am in the despair as soon as I
see
STL source. I am using STLport 5.0-0409 with vc 6.0.

How can I extend STL easily? Any help will be appreciated. Thanks.


One approach is to make a wrapper class for your string and then add
your new functions to it.

class StringWrapper
{
public:
std::string str;
trim_left();
};
You could also make the string member private and provide an access
facade if you prefered, or just leave it public knowing that users could
manipulate it directly.

Brian Rodenborn
Jul 22 '05 #11

P: n/a
If you put a trim_left member function on a string, i would expect "the
string" to be trimmed when calling trim_left(), and would not want a
std::string returned...
But when you have a free function, it operates on the parameter you give it,
and returns a result...

class MyString {
...
public:
...
void trim_left();
...
};

std::string trim_left(const std::string& s);
or
void trim_left(std::string&);

If a trim_left should be a natural function, on a class it would have to be
a "class function"/"static".. And that i would not do for a trim_left...
Syntax being something like
"std::string trimmed = std::string::trim_left( untrimmed );"

So at least for me the free function seems more intuitive... ;)

Jesper

"Kevin W." <co*****@in.sig> wrote in message
news:op**************@localhost.localdomain...
The standard container classes were not designed for inheritance.


How not?
There is no reason to extend a container class to add member functions
because that provides no significant benefits over the non-member
function approach.


Other than semantically. IMO, it's a lot more logical to write
str.trim_left() than trim_left(str).

--
Kevin W :-)
Opera/CSS/webdev blog: http://www.exclipy.com/
Using Opera: http://www.opera.com/m2/

Jul 22 '05 #12

P: n/a
> Logical, or pretty? Lots of the functions in the C++ library are not
member functions (e.g. sin(), sort()), and, for the most part, they
don't seem any more or less logical than the member functions.


sin() acts on a primitive type, so cannot be a member function. sort() is
a generic function, so likewise, cannot be a member of anything. Why are
almost all of the standard library functions that act on strings members
of the string class (this doesn't only apply to strings), and why should
we go against this convention?

Making functions members reinforces the relationship with the class and
reduces the argument count, preventing confusion as to the order of the
arguments.

--
Kevin W :-)
Opera/CSS/webdev blog: http://www.exclipy.com/
Using Opera: http://www.opera.com/m2/
Jul 22 '05 #13

P: n/a
"Kevin W." <co*****@in.sig> wrote in message
news:op**************@localhost.localdomain...
Logical, or pretty? Lots of the functions in the C++ library are not
member functions (e.g. sin(), sort()), and, for the most part, they
don't seem any more or less logical than the member functions.
sin() acts on a primitive type, so cannot be a member function. sort() is
a generic function, so likewise, cannot be a member of anything. Why are
almost all of the standard library functions that act on strings members
of the string class (this doesn't only apply to strings), and why should
we go against this convention?


The std::string class has been attacked by experts for its excessively large
number of members. It has been called a "monolith" class whose members are
more reusable and more understandable as non-members. I would not hold it
up as a model of good design. See Sutter's GOTW about std::string's members
(http://www.gotw.ca/gotw/084.htm). That sort of class design may be a
convention, but it is a convention that has been challenged by a lot of
smart people (see lilburne's reference to the Meyers article for another
example). Their arguments make a lot of sense. That is why we should go
against it.
Making functions members reinforces the relationship with the class and
reduces the argument count, preventing confusion as to the order of the
arguments.


IMHO, reducing an argument count by one doesn't improve anyhing to a
significant degree. There are other equally good ways to express
relationships, like namespaces and header/implementation file organization.

--
David Hilsee
Jul 22 '05 #14

This discussion thread is closed

Replies have been disabled for this discussion.