単純なtemplate <typename T> struct X { T x, y; };
ものとして、ユーザーが次のように記述できるような変換コンストラクターを提供したいと思います。
X<double> a;
X<int16_t> b = a; // uses implicit conversion ctr (compiles with warning)
X<int16_t> c(a); // uses explicit conversion ctr (compiles w/o warning)
X<int32_t> d = c; // uses implicit conversion ctr (compiles w/o warning)
この目標を達成するには、型からの暗黙的および明示的な変換コンストラクターの両方を実装する必要があると思いますU
。ただし、「暗黙的」でオーバーロードすることはできませんexplicit
。
template <typename T> struct X {
X(T x = T(), T y = T()) : x(x), y(y) {}
// implicit conversion
template <typename U>
X(const X<U>& other) : x(other.x), y(other.y) {}
// not possible!
template <typename U>
explicit X(const X<U>& other)
: x(static_cast<T>(other.x))
, y(static_cast<T>(other.y))
{}
T x, y;
};
どうすればこの目標を達成できますか(私はできないと思います...)?
私の最初の考えは、に応じてどちらかを有効/無効にする必要があるということでしたis_lossless_convertible
。それで、適切なタイプの特性はありますか?
スカラー型が精度を失うことなくU
型に変換できるかどうかをテストしたいと思います。T
using namespace std;
static_assert(is_lossless_convertible<int16_t, int32_t>::value == true);
static_assert(is_lossless_convertible<int32_t, int16_t>::value == false);
static_assert(is_lossless_convertible<int16_t, uint32_t>::value == false);
static_assert(is_lossless_convertible<int32_t, double>::value == true);
static_assert(is_lossless_convertible<double, int32_t>::value == false);
つまり、情報の損失に関するコンパイラ警告を発行するかtrue
どうかstd::is_convertible<U, T>::value == true
、また発行しないかどうかを判断する必要があります。U x; T y = x;