Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are C++11 string new functions (stod, stof) not member functions of the string class?

Why are those C++11 new functions of header <string> (stod, stof, stoull) not member functions of the string class ?

Isn't more C++ compliant to write mystring.stod(...) rather than stod(mystring,...)?

like image 285
Greg82 Avatar asked Jan 29 '14 09:01

Greg82


2 Answers

It is a surprise to many, but C++ is not an Object-Oriented language (unlike Java or C#).

C++ is a multi-paradigm language, and therefore tries to use the best tool for the job whenever possible. In this instance, a free-function is the right tool.

Guideline: Prefer non-member non-friend functions to member functions (from Efficient C++, Item 23)

Reason: a member function or friend function has access to the class internals whereas a non-member non-friend function does not; therefore using a non-member non-friend function increases encapsulation.

Exception: when a member function or friend function provides a significant advantage (such as performance), then it is worth considering despite the extra coupling. For example even though std::find works really well, associative containers such as std::set provide a member-function std::set::find which works in O(log N) instead of O(N).

like image 149
Matthieu M. Avatar answered Oct 11 '22 07:10

Matthieu M.


The fundamental reason is that they don't belong there. They don't really have anything to do with strings. Stop and think about it. User defined types should follow the same rules as built-in types, so every time you defined a new user type, you'd have to add a function to std::string. This would actually be possible in C++: if std::string had a member function template to, without a generic implementation, you could add a specialization for each type, and call str.to<double>() or str.to<MyType>(). But is this really what you want. It doesn't seem like a clean solution to me, having everyone writing a new class having to add a specialization to std::string. Putting these sort of things in the string class bastardizes it, and is really the opposite of what OO tries to achieve.

If you were to insist on pure OO, they would have to be members of double, int, etc. (A constructor, really. This is what Python does, for example.) C++ doesn't insist on pure OO, and doesn't allow basic types like double and int to have members or special constructors. So free functions are both an acceptable solution, and the only clean solution possible in the context of the language.

FWIW: conversions to/from textual representation is always a delicate problem: if I do it in the target type, then I've introduced a dependency on the various sources and sinks of text in the target type---and these can vary in time. If I do it in the source or sink type, I make them dependent on the the type being converted, which is even worse. The C++ solution is to define a protocol (in std::streambuf), where the user writes a new free function (operator<< and operator>>) to handle the conversions, and counts on operator overload resolution to find the correct function. The advantage of the free function solution is that the conversions are part of neither the data type (which thus doesn't have to know of sources and sinks) nor the source or sink type (which thus doesn't have to know about user defined data types). It seems like the best solution to me. And functions like stod are just convenience functions, which make one particularly frequent use easier to write.

like image 34
James Kanze Avatar answered Oct 11 '22 09:10

James Kanze