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<>.
#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 ]
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