Boost logo

Boost :

From: Jens Maurer (Jens.Maurer_at_[hidden])
Date: 2001-01-15 16:02:55


Jens Maurer wrote:
> Ok, now we have a nice technical problem to solve: How to allow
> for a rational(long) constructor which works even for rational<long>,
> where we have to avoid ambiguities with the copy constructor.

Option 1: Use template specialization

Define specializations for rational<long> and rational<unsigned long>,
e.g. (abbreviated):

template<class IntType>
class rational
{
public:
  rational(IntType n = 0) : num(n), den(1) { }
  rational(long n) : num(n), den(1) { }
private:
  IntType num, den;
};

template<>
class rational<long>
{
public:
  rational(long n = 0) : num(n), den(1) { }
private:
  long num, den;
};

Option 2: Same as option 1, but define everything except the
constructors in a base class:

template<class IntType>
class rational_base
{
public:
  explicit rational_base(IntType n) : num(n), den(1) { }
  // add other stuff here
private:
  IntType num, den;
};

template<class IntType>
class rational : public rational_base<IntType>
{
public:
  rational(IntType n = 0) : rational_base<IntType>(n) { }
  rational(long n) : rational_base<IntType>(n) { }
  // nothing else needed here
};

template<>
class rational<long> : public rational_base<long>
{
public:
  rational(long n = 0) : rational_base<long>(n) { }
  // nothing else needed here
};

Hm... Looks like explicit specializations are required, because
we need to do away with one offending constructor.

Instead of long/unsigned long you may consider using boost::intmax_t
and boost::uintmax_t from boost/cstdint.hpp, although integer_test.cpp
does not seem to work on Win32 / MSVC 6.0sp4 / STLport 4.0.

Completely unrelated:
We should probably split
    rational(IntType n = 0) : num(n), den(1) {}
into two constructors, because the default-argument version needs an
implicit conversion from int to IntType, which may not exist.

Jens Maurer


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