mirror of
https://gitlab.com/fbb-git/cppannotations
synced 2024-11-16 07:48:44 +01:00
fine tunings
This commit is contained in:
parent
e13a914aef
commit
ac4918a7a9
3 changed files with 36 additions and 28 deletions
|
@ -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
|
||||
|
|
|
@ -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 <class Derived, typename Rhs>
|
||||
|
|
|
@ -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<Derived>) is specified. This allows tt(Binops<Derived>) 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<Derived>) is
|
||||
specified. This allows tt(Binops<Derived>) to define private, inline tt(iWrap)
|
||||
and tt(eWrap) members, merely calling, respectively, tt(Derived's insert) and
|
||||
tt(extract) members:
|
||||
verb(
|
||||
template <typename Derived>
|
||||
inline void Base<Derived>::iWrap(std::ostream &out) const
|
||||
|
@ -18,9 +18,11 @@ tt(Derived's insert) and tt(extract) members:
|
|||
static_cast<Derived const &>(*this).insert(out);
|
||||
}
|
||||
)
|
||||
tt(Base<Derived>) 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<Derived>) 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<Derived>) declaration. Here is the
|
||||
implementation of the overloaded insertion operator:
|
||||
verb(
|
||||
template <typename Derived>
|
||||
std::ostream &operator<<(std::ostream &out, Base<Derived> 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.
|
||||
|
||||
|
|
Loading…
Reference in a new issue