Extend std::string functionality
-
Hello! In my current project I'd like to have some additional std::string functions, like trim[r/l], to_lower/to_upper, split and stuff like that. I know that inheriting from std::string borders on heresy, but I am not sure what else I should do. I could make a file like strtools.h where all the functions I want are defined but that does not fit the OO scheme of std::string and C++ in general. Or I could make a class that does not inherit from std::string but privately uses a variable of that type. That would obey OO rules but it's heck of a lot work to do and I guess there will be some overhead (I haven't tested it yet, so hopefuly you can tell me) What would you recommend me to do and why? Thanks in advance. :)
-
Hello! In my current project I'd like to have some additional std::string functions, like trim[r/l], to_lower/to_upper, split and stuff like that. I know that inheriting from std::string borders on heresy, but I am not sure what else I should do. I could make a file like strtools.h where all the functions I want are defined but that does not fit the OO scheme of std::string and C++ in general. Or I could make a class that does not inherit from std::string but privately uses a variable of that type. That would obey OO rules but it's heck of a lot work to do and I guess there will be some overhead (I haven't tested it yet, so hopefuly you can tell me) What would you recommend me to do and why? Thanks in advance. :)
i usually do it with global (non-class) functions. it's cleaner than going through all the ridiculous hassle of extending std::string.
-
Hello! In my current project I'd like to have some additional std::string functions, like trim[r/l], to_lower/to_upper, split and stuff like that. I know that inheriting from std::string borders on heresy, but I am not sure what else I should do. I could make a file like strtools.h where all the functions I want are defined but that does not fit the OO scheme of std::string and C++ in general. Or I could make a class that does not inherit from std::string but privately uses a variable of that type. That would obey OO rules but it's heck of a lot work to do and I guess there will be some overhead (I haven't tested it yet, so hopefuly you can tell me) What would you recommend me to do and why? Thanks in advance. :)
Be sure to look at Boost String Algorithms Library[^]. It already does what you want, and even if you don't want to use it directly, there is a lot to learn from there.
-
Hello! In my current project I'd like to have some additional std::string functions, like trim[r/l], to_lower/to_upper, split and stuff like that. I know that inheriting from std::string borders on heresy, but I am not sure what else I should do. I could make a file like strtools.h where all the functions I want are defined but that does not fit the OO scheme of std::string and C++ in general. Or I could make a class that does not inherit from std::string but privately uses a variable of that type. That would obey OO rules but it's heck of a lot work to do and I guess there will be some overhead (I haven't tested it yet, so hopefuly you can tell me) What would you recommend me to do and why? Thanks in advance. :)
Write a set of free functions that take const string references and spit out strings modified the way you want. There are a couple of observations here... First one is that just because a function isn't a member of a class doesn't mean that it violates some great principle of OO. A free function can be as much a part of a class's interface even if it's not a member:
class A
{
public:
A &operator+=( const A &add_to );
};A operator+( const A &a, const A &b )
{
A temp( a );
temp += b;
return temp;
}In this example the freestanding
operator+
is very much part of A's interface. As is the usual practice of declaring an insertion and/or extraction operator to do input or output:class B
{
public:
friend std::ostream &operator<<( std::ostream &str, const B &print_me );
friend std::istream &operator>>( std::ostream &str, const B &load_me );
};Second one is that C++ isn't just an OO language. OO is probably the dominant idiom but even hardcore OO programmers use a fair number of generic techniques e.g:
std::string to_upper( const std::string &source )
{
std::string upper_case( source.size(), 0 );
std::transform( begin( source ), end( source), begin( upper_case ), toupper );
return upper_case;
}and:
std::string &to_upper_in_place( std::string &upper_case_me )
{
std::string temp = to_upper( upper_case_me );
std::swap( temp, upper_case_me );
return upper_case_me;
}They're both free functions but the second works very much like you'd defined a member of std::string. Anyway, I've gone on enough. The points I was trying to make are: - free functions can be part of a class's interface - if a class hasn't been built to be extended by inheritance (which
std::string
isn't) then you have to use free functions to extend it -
Write a set of free functions that take const string references and spit out strings modified the way you want. There are a couple of observations here... First one is that just because a function isn't a member of a class doesn't mean that it violates some great principle of OO. A free function can be as much a part of a class's interface even if it's not a member:
class A
{
public:
A &operator+=( const A &add_to );
};A operator+( const A &a, const A &b )
{
A temp( a );
temp += b;
return temp;
}In this example the freestanding
operator+
is very much part of A's interface. As is the usual practice of declaring an insertion and/or extraction operator to do input or output:class B
{
public:
friend std::ostream &operator<<( std::ostream &str, const B &print_me );
friend std::istream &operator>>( std::ostream &str, const B &load_me );
};Second one is that C++ isn't just an OO language. OO is probably the dominant idiom but even hardcore OO programmers use a fair number of generic techniques e.g:
std::string to_upper( const std::string &source )
{
std::string upper_case( source.size(), 0 );
std::transform( begin( source ), end( source), begin( upper_case ), toupper );
return upper_case;
}and:
std::string &to_upper_in_place( std::string &upper_case_me )
{
std::string temp = to_upper( upper_case_me );
std::swap( temp, upper_case_me );
return upper_case_me;
}They're both free functions but the second works very much like you'd defined a member of std::string. Anyway, I've gone on enough. The points I was trying to make are: - free functions can be part of a class's interface - if a class hasn't been built to be extended by inheritance (which
std::string
isn't) then you have to use free functions to extend it -
Be sure to look at Boost String Algorithms Library[^]. It already does what you want, and even if you don't want to use it directly, there is a lot to learn from there.
Good suggestion! :thumbsup:
-
Write a set of free functions that take const string references and spit out strings modified the way you want. There are a couple of observations here... First one is that just because a function isn't a member of a class doesn't mean that it violates some great principle of OO. A free function can be as much a part of a class's interface even if it's not a member:
class A
{
public:
A &operator+=( const A &add_to );
};A operator+( const A &a, const A &b )
{
A temp( a );
temp += b;
return temp;
}In this example the freestanding
operator+
is very much part of A's interface. As is the usual practice of declaring an insertion and/or extraction operator to do input or output:class B
{
public:
friend std::ostream &operator<<( std::ostream &str, const B &print_me );
friend std::istream &operator>>( std::ostream &str, const B &load_me );
};Second one is that C++ isn't just an OO language. OO is probably the dominant idiom but even hardcore OO programmers use a fair number of generic techniques e.g:
std::string to_upper( const std::string &source )
{
std::string upper_case( source.size(), 0 );
std::transform( begin( source ), end( source), begin( upper_case ), toupper );
return upper_case;
}and:
std::string &to_upper_in_place( std::string &upper_case_me )
{
std::string temp = to_upper( upper_case_me );
std::swap( temp, upper_case_me );
return upper_case_me;
}They're both free functions but the second works very much like you'd defined a member of std::string. Anyway, I've gone on enough. The points I was trying to make are: - free functions can be part of a class's interface - if a class hasn't been built to be extended by inheritance (which
std::string
isn't) then you have to use free functions to extend itThis is better than some of the articles we see on here. How about posting this into Tips & Tricks for the benefit of the community as a whole?
-
This is better than some of the articles we see on here. How about posting this into Tips & Tricks for the benefit of the community as a whole?