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'
body - フレンドオペレータからテンプレートラインを削除すると動作しますが、クラス外のフレンドオペレータではオペレータを推論できません。私はコンパイラがこのテンプレート演算子のコードを生成するときに、入力パラメータと戻り値の型が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; }
};
を作品
G ++でもコンパイルされませんが、エラーは異なります。 friend関数のテンプレートパラメータがクラスのテンプレートパラメータを陰影付けすることに戸惑う。暗黙的に20をint_tに変換することもできません。また、値<0uは常に偽です!私は私のスタイルでそれを書き直してみるでしょう、おそらく私は根本的なエラーをキャッチすることができます。 – Frigo
@Frigo:友人宣言はちょっとです(ref。[C++ FAQ Lite 35.16](http://www.parashift.com/c++-faq-lite/templates.html#faq-35.16)eg)。私はMuhammadのコンパイラはそれで大丈夫だと仮定します。 –
私はVC++ 2008コンパイラを使用していますが、言語拡張機能はオフになっており、レベル4の警告が表示されています。 –