Is there such a thing as a C# style extension method in C++?
I'm currently learning C++ and i run into the simple problem of converting an int to a string. I've worked around it using:
string IntToString(int Number)
{
stringstream Stream;
Stream << Number;
return Stream.str();
}
but though it would be more elegant to use something like:
int x = 5;
string y = x.toString();
but how do i add the toString()
method to a built in type?
or am i missin开发者_如何转开发g something totally fundamental?
No, you can't extend classes like that - in C++ the preferred method is to write free functions, as you are doing. These can profitably often be templates:
template <typename T>
string ToString(const T & t)
{
stringstream Stream;
Stream << t;
return Stream.str();
}
which is effectively what lexical_cast
does.
Built-in types or Plain Old Datas like ints do not have methods. The idea of streams is that you can convert anything from anything, not only PODs.
What you are looking for, is a boost::lexical_cast<>, which can work like this:
int i = 12;
std::string s = boost::lexical_cast< std::string >( i );
It can be found in the boost library.
You can do your basic version of this method yourself based on your IntToString method, but templated to work with any types.
template<typename To, typename From >
To my_own_cast(const From & f)
{
std::stringstream stream;
stream << f;
To t;
stream >> t;
return t;
}
used like this:
std::string s;
s = my_own_cast< std::string >( 12 );
int i= my_own_cast< int >( s );
Normally, as far as I know, lexical_cast could be a bit more complex in the last version than just using a stream, and try to be more effecient when it can. It was discussed, I'm not sure it's implemented.
As an alternative, you could overload operator <<
:
string& operator<<(string& str, int Number)
{
stringstream Stream;
Stream << Number;
str = Stream.str();
return str;
}
int x = 5;
string y;
y << x;
Extension methods are not supported by the C++ language. The ideal workaround is a separate function, like you've shown already with IntToString
.
Other alternatives which are not recommended (included only for completeness!) is to derive a class from std::string
and 'extend' it with your own member functions - but deriving from the standard container classes is a bad idea. You could also write your own string class, but why reinvent the wheel? Your IntToString
method is fine, so stick to that.
They are not supported, but the only drawback is a slight lack of notational consistency. You have to write:
SomeClass someInstance;
ToString(someInstance);
instead of:
someInstance.ToString();
This can be somewhat annoying, but it is not a serious problem.
I would not derive any class from basic_string/string. This is not recommended and no method in string is virtual, it does not have a virtual destructor (hence deriving could reault in memory leaks)
Make it pretty for yourself:
You could create a static class (class containing only static methods) in order keep it all in the one place. Use method overloading for int, float, double, etc.
class Converter {
private:
Converter() {}
public:
static string toString(int i) {
... your implementation ...
}
static string toString(float f) {
... same but floats.
}
.... other overloads ....
};
... somewhere else in your code ....
string c = Converter::toString(5);
精彩评论