From ac4918a7a93e78839d20a971380096c3d34259dc Mon Sep 17 00:00:00 2001 From: "Frank B. Brokken" Date: Fri, 10 Feb 2017 21:14:47 +0100 Subject: [PATCH] fine tunings --- annotations/yo/concrete/binop.yo | 7 +++--- annotations/yo/concrete/crtp.yo | 22 ++++++++--------- annotations/yo/concrete/insertion.yo | 35 ++++++++++++++++++---------- 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/annotations/yo/concrete/binop.yo b/annotations/yo/concrete/binop.yo index 5fb30cc0..90f3076f 100644 --- a/annotations/yo/concrete/binop.yo +++ b/annotations/yo/concrete/binop.yo @@ -13,10 +13,9 @@ example). Since template functions are not instantiated before they are actually used we can call non-existing functions from template functions that are never -instantiated. If such a template function is If such a template function is -never instantiated, nothing happens; if it is (accidentally) instantiated, -then the compiler generates an error message, complaining about the missing -function. +instantiated. If such a template function is never instantiated, nothing +happens; if it is (accidentally) instantiated, then the compiler generates an +error message, complaining about the missing function. This allows us to implement all binary operators, movable and non-movable, as templates. In the following subsections we develop the class template diff --git a/annotations/yo/concrete/crtp.yo b/annotations/yo/concrete/crtp.yo index fc67808c..5a3eb2ef 100644 --- a/annotations/yo/concrete/crtp.yo +++ b/annotations/yo/concrete/crtp.yo @@ -60,18 +60,16 @@ The implementation of this free tt(operator+=) function looks like this: } ) ------------------------------------------------------- -The flexibility of this design is augmented -further after realizing that the right-hand side operand doesn't have to be a -tt(Derived) class object. Consider tt(operator<<): oftentimes shifts are -bit-shifts, using a tt(size_t) to specify the number of bits to -shift. In fact, the type of the right-hand side operand can completely be -generalized by defining a second template type parameter, which is used to -specify the right-hand side's operand type. It's up to the tt(Derived) class -to specify the argument type of its tt(operator+=) (or any other binary -compound operator), whereafter the compiler will deduct the types of the -right-hand side operands for the remaining binary operators. Here is the -final implementation of the free +The flexibility of this design can be further augmented once we realize that +the right-hand side operand doesn't have to be a tt(Derived) class +object. Consider tt(operator<<): oftentimes shifts are bit-shifts, using a +tt(size_t) to specify the number of bits to shift. In fact, the type of the +right-hand side operand can completely be generalized by defining a second +template type parameter, which is used to specify the right-hand side's +operand type. It's up to the tt(Derived) class to specify the argument type of +its tt(operator+=) (or any other binary compound operator), whereafter the +compiler will deduct the types of the right-hand side operands for the +remaining binary operators. Here is the final implementation of the free tt(operator+=) function: verb( template diff --git a/annotations/yo/concrete/insertion.yo b/annotations/yo/concrete/insertion.yo index e401deca..0718c613 100644 --- a/annotations/yo/concrete/insertion.yo +++ b/annotations/yo/concrete/insertion.yo @@ -1,16 +1,16 @@ Classes also frequently define overloaded insertion and extraction -operators. Since there are no `compound insertion operators' the approach -covered above cannot be used when overloading these operators. Instead using +operators. Since there are no `compound insertion operators' the design shown +so far cannot be used when overloading these operators. Instead using standardized member function signatures is advocated: tt(void insert(std::ostream &out) const) to insert an object into an tt(ostream) and tt(void extract(std::istream &in) const) to extract an object from an -tt(istream). As these functions are only used by, respectively, the -insertion and extraction operators, they can be declared in the tt(Derived) -class's private interface. Instead of declaring the insertion and extraction -operators friends of the class tt(Derived) a simpler tt(friend -Binops) is specified. This allows tt(Binops) to define -private, inline tt(iWrap) and tt(eWrap) members, merely calling, respectively, -tt(Derived's insert) and tt(extract) members: +tt(istream). As these functions are only used by, respectively, the insertion +and extraction operators, they can be declared in the tt(Derived) class's +private interface. Instead of declaring the insertion and extraction operators +friends of the class tt(Derived) a single tt(friend Binops) is +specified. This allows tt(Binops) to define private, inline tt(iWrap) +and tt(eWrap) members, merely calling, respectively, tt(Derived's insert) and +tt(extract) members: verb( template inline void Base::iWrap(std::ostream &out) const @@ -18,9 +18,11 @@ tt(Derived's insert) and tt(extract) members: static_cast(*this).insert(out); } ) - tt(Base) also declares the insertion and extraction operators -as its friends, allowing these operators to call, respectively, tt(iWrap) and -tt(eWrap). Here is the implementation of the overloaded insertion operator: + tt(Base) then declares the insertion and extraction operators as +its friends, allowing these operators to call, respectively, tt(iWrap) and +tt(eWrap). Note that the software engineer designing the class tt(Derived) +only has to provide a tt(friend Base) declaration. Here is the +implementation of the overloaded insertion operator: verb( template std::ostream &operator<<(std::ostream &out, Base const &obj) @@ -29,3 +31,12 @@ tt(eWrap). Here is the implementation of the overloaded insertion operator: return out; } ) + +This completes the coverage of the essentials of a class template tt(Binops) +potentially offering binary operators and insertion/extraction operators for +any class derived from tt(Binops). Finally, as noted at the beginning of this +section, a complete implementation of a class offering addition and insertion +operators is provided in the file +tt(annotations/yo/concrete/examples/binopclasses.cc) in the annotations()' +source archive. +