У меня есть следующий класс
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; }
при выполнении следующего кода
typedef int_t<long long, unsigned long long> int128;
int main()
{
int128 i = 1024;
i = i + 20;
}
компилятор выдаст ошибку:
'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'
когда я помещаю код оператора шаблона в тело класса - с удалением строки шаблона из оператора друга - он работает, но с оператором друга вне класса он не может вывести оператор. я думал, что когда компилятор сгенерирует код для этого оператора шаблона, входные параметры и возвращаемое значение будут иметь тип int128
, поэтому у него не должно возникнуть проблем с приведением типа int к этому типу.
UPDATE
если мы определили оператор друга внутри класса следующим образом, работает предыдущий пример
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; }
};
проблема возникает при попытке определить оператор шаблона вне класса