Boost logo

Boost :

From: scleary_at_[hidden]
Date: 2000-10-10 13:56:55


> I haven't written anything for this yet, but I was thinking of making a
> certain kind of a numeric adapter class. It should support all the
> arithmetic operations the base type supports.
>
> The problem is the modulus operators. They should be defined only if the
> base type is integral. I can check this from the base type's
> std::numeric_limits implementation. The value should be a compile-time
> constant, so I can use it as a template parameter.
>
> So I could make one version of my adapter class that includes modulus
> operations, and one that doesn't. But I want the end user to see only one
> adapter class, which would secretly inherit(?) from one of the specialized
> adapter classes (based on the numeric-limit compile-time constant). How
> would I do it, or do I have to settle for a single adapter class without
> modulus operations?
>
> (I know this technique can work for template functions. For example, the
> iterator std::distance function could specialize for different iterator
> types by secretly calling another function that takes the iterator's type
> tag as an extra argument. I'm asking for a similar technique for template
> classes.)

I think I know what you're getting at here. If I misunderstand you, let me
know. You can partially specialize a template base class:

  namespace details {

  template <typename Derived, bool IsIntegral>
  struct numeric_adapter_integral_base;
  template <typename Derived>
  struct numeric_adapter_integral_base<Derived, true>
  {
    // Replace with the correct function signature(s)
    // for any integer-specific operations
    // (I'm not sure what your adapter does)
    Derived & operator%=(const Numeric & rhs)
    {
      ... // whatever
      // you can access the derived type as:
      // static_cast<Derived &>(*this);
    }
  };
  template <typename Derived>
  struct numeric_adapter_integral_base<Derived, false>
  { /* empty: no additional operations for non-integrals */ };

  } // namespace details

  template <typename Numeric>
  class numeric_adapter:
      public details::numeric_adapter_integral_base<
          numeric_adapter<Numeric>,
          std::numeric_limits<Numeric>::is_integer >
  {
    ... // any generic numeric operations
  };

This example uses the Barton & Nackman technique. Read the Boost
documentation for the "operators" library, which deals with several of the
same problems at:
  http://www.boost.org/libs/utility/operators.htm
or my page on the Barton/Nackman technique at:
 
http://my.voyager.net/~shammah/TBA/docs/main/techniques/barton_nackman.html

        -Steve


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk