読者です 読者をやめる 読者になる 読者になる

二項演算子をクラス内でオーバーロードしたテンプレートクラスをテンプレート関数で返してdecltype内で演算すると C2677 エラーが起きて最高に意味不明

template<class>
struct rhs
{
	friend int operator*(int x, rhs){ return 2; }
};

template<class T>
rhs<T> make(T){ return rhs<T>(); }
using R = decltype(42 * make(42));
int main(){}
  1. 自身が右辺に来る二項演算子
  2. クラス内でオーバーロードした
  3. テンプレートクラスを
  4. テンプレート関数で返し
  5. decltype内で演算する

=>C2677エラー!!

最高に意味不明
対処法はrhs内でoperator*をオーバーロードせず外部で定義すればよい
色々と試したところ

  • decltypeを通さず普段通り演算した場合には問題ない
  • 関数とクラスどちらもテンプレートでないと発生しない
  • 左辺の場合は起こらない
  • operator |など二項演算子で起こる
  • コンパイラでは通る

最高に意味不明