Why are those C++11 new functions of header <string>
(stod
, stof
, stoull
) not member functions of the string
class ?
为什么那些c++ 11新函数的标题
Isn't more C++ compliant to write mystring.stod(...)
rather than stod(mystring,...)
?
编写mystring.stod(…)而不是stod(mystring,…)不是更符合c++的要求吗?
3 个解决方案
#1
22
It is a surprise to many, but C++ is not an Object-Oriented language (unlike Java or C#).
这对许多人来说是一个惊喜,但是c++不是一种面向对象的语言(不像Java或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.
c++是一种多模式语言,因此尽可能地使用最好的工具。在本例中,*函数是正确的工具。
Guideline: Prefer non-member non-friend functions to member functions (from Efficient C++, Item 23)
指南:更喜欢非成员非朋友函数而非成员函数(来自高效c++,第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).
例外:当成员函数或朋友函数提供了显著的优势(比如性能)时,尽管存在额外的耦合,但仍然值得考虑。例如,即使std::find工作得非常好,但是像std::set这样的关联容器提供了一个成员函数std::set::find哪个在O(log N)而不是O(N)中工作。
#2
3
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.
根本原因是它们不属于那里。它们和字符串没有任何关系。停下来想一想。用户定义的类型应该遵循与内置类型相同的规则,因此每次定义一个新的用户类型时,都必须向std::string添加一个函数。在c++中,这实际上是可能的:如果std::string有一个成员函数模板,没有通用的实现,您可以为每个类型添加一个专门化,并调用string .to
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.
如果您坚持使用纯OO,那么它们必须是double、int等(实际上是构造函数)的成员。这就是Python所做的事情。c++不坚持纯OO,也不允许像double和int这样的基本类型具有成员或特殊构造函数。因此,*函数既是一种可接受的解决方案,也是在语言环境中唯一可能的干净解决方案。
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.
FWIW:转换到/从文本表示始终是一个微妙的问题:如果我在目标类型中进行转换,那么我就引入了对目标类型中文本的各种来源和接收的依赖——而且这些内容会随时间而变化。如果我在source或sink类型中执行,我会使它们依赖于正在转换的类型,这甚至更糟糕。c++解决方案是定义一个协议(在std::streambuf中),用户在其中编写一个新的*函数(操作符 <和操作符> >)来处理转换,并计算操作符重载解析以找到正确的函数。*函数解决方案的优点是,转换既不属于数据类型(因此不需要知道源和汇聚),也不属于源或汇聚类型(因此不需要知道用户定义的数据类型)。对我来说这似乎是最好的解决办法。而像stod这样的函数仅仅是一种方便的函数,这使得人们更容易编写。
#3
1
Actually they are some utility functions and they don't need to be inside the main class. Similar utility functions such as atoi, atof are defined (but for char*) inside stdlib.h and they too are standalone functions.
实际上它们是一些实用函数它们不需要在主类中。在stdlib中定义了类似的实用函数,如atoi、atof(但是对于char*)。h和它们也是独立的函数。
#1
22
It is a surprise to many, but C++ is not an Object-Oriented language (unlike Java or C#).
这对许多人来说是一个惊喜,但是c++不是一种面向对象的语言(不像Java或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.
c++是一种多模式语言,因此尽可能地使用最好的工具。在本例中,*函数是正确的工具。
Guideline: Prefer non-member non-friend functions to member functions (from Efficient C++, Item 23)
指南:更喜欢非成员非朋友函数而非成员函数(来自高效c++,第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).
例外:当成员函数或朋友函数提供了显著的优势(比如性能)时,尽管存在额外的耦合,但仍然值得考虑。例如,即使std::find工作得非常好,但是像std::set这样的关联容器提供了一个成员函数std::set::find哪个在O(log N)而不是O(N)中工作。
#2
3
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.
根本原因是它们不属于那里。它们和字符串没有任何关系。停下来想一想。用户定义的类型应该遵循与内置类型相同的规则,因此每次定义一个新的用户类型时,都必须向std::string添加一个函数。在c++中,这实际上是可能的:如果std::string有一个成员函数模板,没有通用的实现,您可以为每个类型添加一个专门化,并调用string .to
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.
如果您坚持使用纯OO,那么它们必须是double、int等(实际上是构造函数)的成员。这就是Python所做的事情。c++不坚持纯OO,也不允许像double和int这样的基本类型具有成员或特殊构造函数。因此,*函数既是一种可接受的解决方案,也是在语言环境中唯一可能的干净解决方案。
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.
FWIW:转换到/从文本表示始终是一个微妙的问题:如果我在目标类型中进行转换,那么我就引入了对目标类型中文本的各种来源和接收的依赖——而且这些内容会随时间而变化。如果我在source或sink类型中执行,我会使它们依赖于正在转换的类型,这甚至更糟糕。c++解决方案是定义一个协议(在std::streambuf中),用户在其中编写一个新的*函数(操作符 <和操作符> >)来处理转换,并计算操作符重载解析以找到正确的函数。*函数解决方案的优点是,转换既不属于数据类型(因此不需要知道源和汇聚),也不属于源或汇聚类型(因此不需要知道用户定义的数据类型)。对我来说这似乎是最好的解决办法。而像stod这样的函数仅仅是一种方便的函数,这使得人们更容易编写。
#3
1
Actually they are some utility functions and they don't need to be inside the main class. Similar utility functions such as atoi, atof are defined (but for char*) inside stdlib.h and they too are standalone functions.
实际上它们是一些实用函数它们不需要在主类中。在stdlib中定义了类似的实用函数,如atoi、atof(但是对于char*)。h和它们也是独立的函数。