In [1]:
.rawInput


Using raw input
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


Not using raw input
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;


division entière : 2, réelle : 2.66667
Out[4]:
(std::basic_ostream<char, std::char_traits<char> >::__ostream_type &) @0x7f579ac2ee40

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;


5.66667
Out[5]:
(std::basic_ostream<char, std::char_traits<char> >::__ostream_type &) @0x7f579ac2ee40

In [ ]: