オーバーフロー/アンダーフローのエラーを検出するのに役立つ算術ラッパーを作成しましたが、プロセスでかなり重大な問題があります。テンプレートの戻り値の型を変更すると、オーバーロードの解像度に影響があるように見えます
いくつかのオーバーロードされた演算子を介してオーバーフローを引き起こす可能性のあるすべてのものを処理し、他のすべてのものについては潜在的な型に暗黙的にキャスト可能なクラスがあるとします。この例では、バイナリプラス演算子が含まれています。これは、(基本的には、それらのすべての可能な1)(ここでそれを貼り付けている間、私は何かを逃さなかった場合)、罰金コンパイルし、このような状況では期待通りに を働く
template<typename T_>
class Wrapper
{
public:
Wrapper(T_ val_) : m_value(val_) { } // converting constructor
operator T_(void) const { return m_value; } // underlying type conversion
// some other methods
// binary plus operators:
template<typename U_>
const Wrapper<decltype(T_() + U_())> operator +(U_ val_) const
{
// supposed to handle 'Wrapped + Unwrapped' case
return m_value + val_;
}
template<typename U_>
const Wrapper<decltype(T_() + U_())> operator +(Wrapper<U_> other_) const
{
// supposed to handle 'Wrapped + Wrapped' case
return m_value + other_.m_value;
}
template<typename U0_, typename U1_>
friend const Wrapper<decltype(U0_() + U1_())> operator +(U0_ val_, Wrapper<U1_> wrapper_)
{
// supposed to handle 'Unwrapped + Wrapped' case
return val_ + wrapper_.m_value;
}
private:
T_ m_value;
};
:しかし
Wrapper<int> val = 3.14f;
::std::cout << val + 42 << ::std::endl; // Wrapped + Unwrapped
::std::cout << 42 + val << ::std::endl; // Unwrapped + Wrapped
::std::cout << val + val << ::std::endl; // Wrapped + Wrapped
、私は「+ラップアンラップ」または、次のように例えば「ラップアンラップ+」のいずれかのdecltype(...)
一部のエイリアスを作成しようとするたびに:
template<typename T0_, typename T1_>
struct Result
{
typedef decltype(T0_() + T1_()) Type;
};
template<typename T_>
class Wrapper
{
//...
template<typename U_>
const Wrapper<typename Result<T_, U_>::Type> operator +(U_ val_) const
//...
template<typename U0_, typename U1_>
friend const Wrapper<typename Result<U0_, U1_>::Type> operator +(U0_ val_, Wrapper<U1_> wrapper_)
//...
};
「ラップされた+ラップされた」例は、望ましくない変形に向かって過負荷の解像度が変化するように見えるため、コンパイルしたくありません。 Wrapper<int>
の既定のコンストラクタが使用できないというエラーがスローされ、問題のケースを適切に処理するのに適していない「ラップ+アンラップ」または「ラップ解除+ラップ」のいずれかを使用しようとしています。
戻り値の型が変わると、オーバーロードの解決動作が変化するように見えます。この問題に関するアドバイスをいただければ幸いです。
を。潜在的に無効な式が 'Result'の定義に移され、直後のコンテキストの外に移動されたためです。 –
このような状況で過負荷を解消するためには、「ラップされた+ラップされた」変種がより適切なものと見なされることを最初から間違っていました。あなたは答えのためにお会いしましょう。 – so100217
(部分的な順序付けなどのために)うまく過負荷になるかもしれませんが、そこにも到達しません。候補のセットを形成しようとすると、ハードエラーが発生します。 –