C ++ - semantic type of packaging

I have a data type like class Vector3 . Now I need to create several classes with the same interface as Vector3 , but with a higher level of semantics (for example: Position , Velocity ). Using typedef not enough, because I need these types to be different so that they can be used for overloading. In C ++ 0x, I could probably use constructor inheritance:

 struct Position: public Vector3 { using Vector3::Vector3; }; 

Could there be any problems with this? Is there a better way to do this? Is it possible to do this without using the features of C ++ 0x and not write explicitly all Vector3 constructors?

+6
source share
2 answers

Consider using the struct tag

 struct tagPosition {}; struct tagDirection {}; struct tagGeneric {}; namespace detail { template <typename Tag=tagGeneric> class Vector3 { // business as usual }; } typedef detail::Vector3<tagPosition> Position; typedef detail::Vector3<tagDirection> Direction; typedef detail::Vector3<tagGeneric> Vector3; 

For bonus points, there are conversion operators / constructors:

  template <typename Tag=tagGeneric> class Vector3 { template <typename OtherTag> explicit Vector3(const Vector3<OtherTag>& rhs) { /* ... */ } // template <typename OtherTag> // operator Vector3<OtherTag>() const { return /* ... */ } }; 

If you enjoy living dangerously, you can opt out of the explicit keyword or enable the implicit conversion operator. This would have the β€œbenefit” of being able to allow promiscuous operating permissions:

  Position pos; Direction dir; Generic gen; dir = gen + pos; // you see why I call it 'promiscuous'? 

I would recommend (instead) define explicit operators for such cases (free functions :)

  Position operator+(const Position& v, const Translation& d) { /* .... */ } 

Thus, the model of your class reflects the semantics of your classes.

C ++ 0x probably contains things to include explicit conversion operators , IIRC:

In the case of constructor conversions, you can turn off implicit conversions by declaring the constructor as explicit. Proposal N1592 extends the semantics of this keyword to all conversion operators. An explicit conversion statement will not perform an implicit conversion. Instead, the programmer will have to explicitly call it

+5
source

When I need different, but similar types, I usually used a dummy template parameter, for example (from a cuff untouched by the dirty hands of the compiler)

 template< class UniqueId > struct Blah {}; typedef Blah< struct AlphaId > Alpha; typedef Blah< struct BetaId > Beta; 

This may or may not be what you need.

Cheers and hth.,

+4
source

Source: https://habr.com/ru/post/890742/


All Articles