Overloading

Because unsigned_int<> lacks the implicit conversion characteristics of inbuilt unsigned certain overload selection problems that we might expect unsigned to handle aren't handled by unsigned_int<>.

Example that fails

#include "imp/unsigned_int.hpp"
using namespace imp;

void overload( double )
{
}
void overload( int )
{
}

int main()
{
  unsigned_int< 128 > a;

  overload( a );
}

Test Result: gcc34 Passed, msvc80 Passed, msvc71 Passed

Warning

./gensrc/overload-id-fail.cpp:15:
: 'overload' : ambiguous call to overloaded function
./gensrc/overload-id-fail.cpp:7:
could be 'void overload(int)'
./gensrc/overload-id-fail.cpp:4:
or       'void overload(double)'
        while trying to match the argument list '(imp::unsigned_int_s::unsigned_int<N>)'
        with
        [
            N=128
        ]

Example that works

This example "solves" the problem by adding a further templated overload void overload( unsigned_int< N > const & ) which just forwards to the desired function.

#include <iostream>
#include <ostream>
#include "imp/unsigned_int.hpp"
using namespace imp;

void overload( double )
{
  std::cout << "double\n";
}
void overload( int )
{
  std::cout << "int\n";
}


/* template that instantiates as an exact match
   without this there is an ambiguity
*/
template < unsigned N >
inline void overload( unsigned_int< N > const &arg )
{
  std::cout << "unsigned_int< N > [ with N = " << N << " ]\n";

  /* ERROR for MSVC 7.1 -- fails to instantiate operator <> double ()
     with overload( double( arg ) ); see main()
  */

  unsigned_int< N > a = arg;

  overload( double( a ) );
}

int main()
{
  unsigned_int< 128 > a;

  /* MSVC7.1 instantiate unsigned_int< 128 >::operator<double> double();
  */
  (double)a;

  overload( a );
}

Test Result: gcc34 Passed, msvc80 Passed, msvc71 Passed

Output

unsigned_int< N > [ with N = 128 ]
double