私は、より効果的な C++ の項目 22 にある Scott Meyers のアドバイスに従おうとしています:「op=
スタンドアロンではなく使用を検討してくださいop
」。彼は、 のテンプレートを作成してoperator+
、実装するすべてのクラスがoperator+=
自動的に を取得できるようにすることを提案していoperator+
ます。
template<class T>
const T operator+(const T& lhs, const T& rhs)
{
return T(lhs) += rhs;
}
さて、Effective Modern C++ の項目 25 には、行列の加算の例 (pg. 172) があります。そこでは、右辺値を使用したオーバーロードoperator+
が提案されていますlhs
。rhs
おそらく巨大な行列の無用なコピー。だから私はオーバーロードを追加しました:
template<class T>
T operator+(T&& lhs, const T& rhs)
{
return std::move(lhs += rhs);
}
template<class T>
T operator+(T const& lhs, T&& rhs)
{
return std::move(rhs += lhs);
}
template<class T>
T operator+(T&& lhs, T&& rhs)
{
return std::move(lhs += rhs);
}
ここでの問題は、それT&&
が普遍的な参照であり、すべてをキャプチャすることになるため、左辺値から移動することになりますが、これは望ましくない動作です。
operator+
では、テンプレートを適切に実装するにはどうすればよいでしょうか。
値渡しを使用した部分的な解決策:アイテム 41: "コピー可能なパラメーターの値渡しを検討してください..." も読んだので、Effective Modern C++ から、次のような独自のバージョンを作成しようとしました。
template<class T>
const T operator-(T lhs, T rhs)
{
return lhs -= rhs;
}
しかし、rhs が右辺値の場合、これは最適化の機会を逃します。この場合、rhs を使用して結果を格納しないからです。したがって、これは部分的な解決策にすぎません。