Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
324 views
in Technique[技术] by (71.8m points)

c++ - What is a "Regular Type" in the context of move semantics?

Alex Stepanov defined Regular Types as types satisfying certain properties around copying and equality. Now that C++11 has added move semantics to the realm of generic programming, Stepanov's definition is no longer complete. I'm looking for a good reference on regular types that includes their interaction with move semantics.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Summary:

For C++11 I would include:

  • move-ctor (noexcept)
  • move-assign (noexcept)
  • total ordering (operator<() for natural total order and std::less<> if a natural total order does not exist).
  • hash<>

And would remove:

  • swap() (non-throwing) - replaced by move operations.

Commentary

Alex revisits the concept of a regular type in Elements of Programming. In fact, much of the book is devoted to regular types.

There is a set of procedures whose inclusion in the computational basis of a type lets us place objects in data structures and use algorithms to copy objects from one data structure to another. We call types having such a basis regular, since their use guarantees regularity of behavior and, therefore, interoperability. -- Section 1.5 of EoP

In EoP, Alex introduces the notion of an underlying_type which gives us a non-throwing swap algorithm that can be used to move. An underlying_type template isn't implementable in C++ in any particularly useful manner, but you can use non-throwing (noexcept) move-ctor and move-assign as reasonable approximations (an underlying type allows moving to/from a temporary without an additional destruction for the temporary). In C++03, providing a non-throwing swap() was the recommended way to approximate a move operation, if you provide move-ctor and move-assign then the default std::swap() will suffice (though you could still implement a more efficient one).

[ I'm on record as recommending that you use a single assignment operator, passing by value, to cover both move-assign and copy-assign. Unfortunately the current language rules for when a type gets a default move-ctor causes this to break with composite types. Until that is fixed in the language you will need to write two assignment operators. However, you can still use pass by value for other sink arguments to avoid combinatorics in handling move/copy for all arguments. ]

Alex also adds the requirement of total ordering (though there may not be a natural total order and the ordering may be purely representational). operator<() should be reserved for the natural total ordering. My suggestion is to specialize std::less<>() if a natural total ordering is not available, there is some precedent for that in the standard).

In EoP, Alex relaxes the requirements on equality to allow for representational-equality as being sufficient. A useful refinement.

A regular type should also be equationally complete (that is, operator==() should be implementable as a non-friend, non-member, function). A type that is equationally complete is also serializable (though without a canonical serialization format, implementing the stream operators are of little use except for debugging). A type that is equationally complete can also be hashed. In C++11 (or with TR1) you should provide a specialization of std::hash.

Another property of regular types is area() for which there is not yet any standard syntax - and likely little reason to actually implement except for testing. It is a useful concept for specifying complexity - and I frequently implement it (or an approximation) for testing complexity. For example, we define the complexity of copy as bounded by the time to copy the area of the object.

The concept of a regular type is not language-specific. One of the first things I do when presented with a new language is work out how regular types manifest in that language.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...