text: From: Ed Brey (brey_at_[hidden])
  Date: 2001-04-25 15:38:18
  From: "Mark Rodgers" <mark.rodgers_at_[hidden]>
  > > Usage would typically be:
  > > typedef boost::math::constants<float> c;
  > > a = c::pi() * r * r;
  >
  > As an aside, wouldn't it be nice if we could have template namespaces?
  Then
  > you could write
  >
  > using boost::math::constants<float>::pi;
  > a = pi() * r * r;
  >
  > and we also be able to reopen the boost::math::constants<T> namespace
  to
  > add more members in other header files if desired.
  >
  > Anyway, back to the real world.
  The real world can be surprising. At least it surprised me. The
  following actually compiled (and hopefully is legal C++):
  float (&pi)() = boost::math::constants<float>::pi;
  a = pi() * r * r;
  So in a way, you have template namespaces; only they're called
  references.
  > I've been out of things for a while. Was the following option
  discussed,
  > and if so what is wrong with it?
  >
  > #include <iostream>
  >
  > namespace boost { namespace math { namespace constants {
  > template<typename T> T pi();
  >
  > template<> float pi<float>() {return 3.14F;}
  > template<> double pi<double>() {return 3.14;}
  > template<> long double pi<long double>() {return 3.14L;}
  > } } }
  >
  > using boost::math::constants::pi;
  > a = pi<float>() * r * r;
  I addressed this issue briefly once before. The problems with this
  usage pattern are scalability and design-time garbage collection. When
  you use a lot of constants, it means having to write a lot of extra code
  in the form of using declarations, and it can be difficult to determine
  when you can get rid of a using declaration during program maintenance.
  There don't seem to be too many math constants, and so its a so-so
  problem with this library; however, I expect physical constant libraries
  to have more constants that one may use, which does start posing a more
  real problem.
  However, the interface you propose also allows this usage:
  namespace c = boost::math::constants;
  a = c::pi<float>() * r * r;
  Which gets around the scalability issue. And of course, the user can
  always define a reference for any constant that he didn't want to have
  to qualify with the renamed namespace and the template argument. The
  one thing you can't do in this approach is get access to a bunch of
  constants of the same type, with a single declaration, e.g. (using the
  struct-based interface):
  template<typename T>
  T compute(T x, T y) {
  typedef boost::math::constants<T> c;
  T e = a * c::pi();
  T f = y * c::e();
  if (e > 0) f = -1;
  return e * f * c::sqrt2();
  }
  This functionality puts the structure-based approach over the top, for
  me.
  Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk