In [1]:
.rawInput
Out[1]:
In [2]:
#include <variant>
#include <type_traits>
#include <cstdint>
#include <iostream>
class NumericOp
{
public:
NumericOp()
: numeric(static_cast<int64_t>(0))
{}
// Implicite conversion entière
template <typename T, typename IntegralT = std::enable_if_t<std::is_integral_v<T> > >
NumericOp(T i)
: numeric(static_cast<int64_t>(i))
{}
// Implicite conversion réélle
template <typename T, typename IntegralT = void, typename FloatingT = std::enable_if_t<std::is_floating_point_v<T> > >
NumericOp(T d)
: numeric(static_cast<double>(d))
{}
// Explicite conversion vers un type "Integral"
template <typename T, typename IntegralT = std::enable_if_t<std::is_integral_v<T> > >
explicit operator T() const
{
return static_cast<T>(std::get<int64_t>(numeric));
}
// Explicite conversion vers un type "Floating point"
template <typename T, typename IntegralT = void, typename FloatingT = std::enable_if_t<std::is_floating_point_v<T> > >
explicit operator T() const
{
return static_cast<T>(std::get<double>(numeric));
}
NumericOp operator/(const NumericOp& rhs) const
{
return std::visit([](auto&& arg1, auto&& arg2){return NumericOp(arg1 / arg2);}, numeric, rhs.numeric);
}
friend std::ostream& operator<<(std::ostream& out, const NumericOp& n);
private:
std::variant<int64_t,double> numeric;
};
std::ostream& operator<<(std::ostream& os, const NumericOp& n)
{
std::visit([&os](auto&& arg){os << arg;}, n.numeric);
return os;
}
Out[2]:
In [3]:
.rawInput
Out[3]:
In [4]:
unsigned short divisor = 3U;
NumericOp a(8), b(8.0);
NumericOp e = a / divisor;
NumericOp r = b / divisor;
std::cout << "division entière : " << e << ", réelle : " << r << std::endl;
Out[4]:
In [5]:
float c = 3.0;
// operateur de cast pour la compatibilité avec les fonctions prenant un type float.
std::cout << (c + static_cast<float>(r)) << std::endl;
Out[5]:
In [ ]: