I have the following class
template<typename hi_t, typename lo_t>
struct int_t
{
hi_t hi;
lo_t lo;
int_t() : lo(0), hi(0) {}
int_t(int value) : lo(value), hi( value<0u? -1: 0 ) {}
int_t(unsigned value) : lo(value), hi( 0 ) {}
int_t& operator+=(const int_t& rhs)
{
lo_t _lo = lo;
lo += rhs.lo;
hi += rhs.hi;
hi += (int)(lo < _lo);
return *this;
}
template<typename hi_t, typename lo_t>
inline friend int_t<hi_t, lo_t> operator+(const int_t<hi_t, lo_t>&, const int_t<hi_t, lo_t>&);
};
template<typename hi_t, typename lo_t>
int_t<hi_t, lo_t> operator+(const int_t<hi_t, lo_t>& lhs, const int_t<hi_t, lo_t>& rhs)
{ return int_t<hi_t, lo_t>(lhs) += rhs; }
when executing the following code
typedef int_t<long long, unsigned long long> int128;
int main()
{
int128 i = 1024;
i = i + 20;
}
the compiler produce the error:
'int_t<hi_t,lo_t> operator +(const int_t<hi_t,lo_t> &,const int_t<hi_t,lo_t> &)' : could not deduce template argument for 'const int_t<hi_t,lo_t> &' from 'int'
when i put the code of template operator inside the class body - with removing the template line from the friend operator - it works, but with friend operator outside the class it can't deduce the operator. i thought when compiler generates code for this template operator the input parameters and return value will be of type int128
so it should have no problem from casting from int to that type.
UPDATE
if we define the friend operator inside the class as following the previous example works
template<typename hi_t, typename lo_t>
struct int_t
{
hi_t hi;
lo_t lo;
int_t() : lo(0), hi(0) {}
int_t(int value) : lo(value), hi( value<0u? -1: 0 ) {}
int_t(unsigned value) : lo(value), hi( 0 ) {}
int_t& operator+=(const int_t& rhs)
{
lo_t _lo = lo;
lo += rhs.lo;
hi += rhs.hi;
hi += (int)(lo < _lo);
return *this;
}
friend int_t operator+(const int_t& lhs, const int_t& rhs)
{ return int_t(lhs) += rhs; }
};
the problem happens when trying to define the template operator outside the class