title: Wrapping arithmetic types in C++
body: <p>C++ is awesome, but you cannot inherit from arithmetic types, which, sometimes, would be useful. I wrote the following:</p>
  
  <pre><code>template &lt;typename type&gt; class arithmetic
  {
      static_assert(std :: is_arithmetic &lt;type&gt; :: value, "Please provide an arithmetic type.");
  
      // Members
  
      type _value;
  
  public:
  
      // Constructors
  
      inline arithmetic() = default;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline arithmetic(const rtype &amp;);
  
      // Arithmetic operators
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator + (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator - (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator * (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator / (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator % (const rtype &amp;) const;
  
      inline auto operator + () const;
      inline auto operator - () const;
  
      inline auto operator ++ ();
      inline auto operator ++ (int);
  
      inline auto operator -- ();
      inline auto operator -- (int);
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator = (const rtype &amp;);
  
      // Comparison operators
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator == (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator != (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator &gt; (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator &lt; (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator &gt;= (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator &lt;= (const rtype &amp;) const;
  
      // Logical operators
  
      inline auto operator ! () const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator &amp;&amp; (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator || (const rtype &amp;) const;
  
      // Bitwise operators
  
      inline auto operator ~ () const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator &amp; (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator | (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator ^ (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator &lt;&lt; (const rtype &amp;) const;
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator &gt;&gt; (const rtype &amp;) const;
  
      // Compound assignment operators
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator += (const rtype &amp;);
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator -= (const rtype &amp;);
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator *= (const rtype &amp;);
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator /= (const rtype &amp;);
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator %= (const rtype &amp;);
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator &amp;= (const rtype &amp;);
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator |= (const rtype &amp;);
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator ^= (const rtype &amp;);
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator &lt;&lt;= (const rtype &amp;);
  
      template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type * = nullptr&gt; inline auto operator &gt;&gt;= (const rtype &amp;);
  
      // Member and pointer operators
  
      inline type * operator &amp; ();
      inline const type * operator &amp; () const;
  
      // Casting
  
      inline operator type &amp; ();
      inline operator const type &amp; () const;
  };
  
  // Constructors
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline arithmetic &lt;type&gt; :: arithmetic(const rtype &amp; value) : _value(value)
  {
  }
  
  // Arithmetic operators
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator + (const rtype &amp; rvalue) const
  {
      return this-&gt;_value + rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator - (const rtype &amp; rvalue) const
  {
      return this-&gt;_value - rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator * (const rtype &amp; rvalue) const
  {
      return this-&gt;_value * rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator / (const rtype &amp; rvalue) const
  {
      return this-&gt;_value / rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator % (const rtype &amp; rvalue) const
  {
      return this-&gt;_value % rvalue;
  }
  
  template &lt;typename type&gt; inline auto arithmetic &lt;type&gt; ::  operator + () const
  {
      return +(this-&gt;_value);
  }
  
  template &lt;typename type&gt; inline auto arithmetic &lt;type&gt; ::  operator - () const
  {
      return -(this-&gt;_value);
  }
  
  template &lt;typename type&gt; inline auto arithmetic &lt;type&gt; ::  operator ++ ()
  {
      return ++(this-&gt;_value);
  }
  
  template &lt;typename type&gt; inline auto arithmetic &lt;type&gt; ::  operator ++ (int)
  {
      return (this-&gt;_value)++;
  }
  
  template &lt;typename type&gt; inline auto arithmetic &lt;type&gt; ::  operator -- ()
  {
      return --(this-&gt;_value);
  }
  
  template &lt;typename type&gt; inline auto arithmetic &lt;type&gt; ::  operator -- (int)
  {
      return (this-&gt;_value)++;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator = (const rtype &amp; rvalue)
  {
      return this-&gt;_value = rvalue;
  }
  
  // Comparison operators
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator == (const rtype &amp; rvalue) const
  {
      return this-&gt;_value == rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator != (const rtype &amp; rvalue) const
  {
      return this-&gt;_value != rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator &gt; (const rtype &amp; rvalue) const
  {
      return this-&gt;_value &gt; rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator &lt; (const rtype &amp; rvalue) const
  {
      return this-&gt;_value &lt; rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator &gt;= (const rtype &amp; rvalue) const
  {
      return this-&gt;_value &gt;= rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator &lt;= (const rtype &amp; rvalue) const
  {
      return this-&gt;_value &lt;= rvalue;
  }
  
  // Logical operators
  
  template &lt;typename type&gt; inline auto arithmetic &lt;type&gt; ::  operator ! () const
  {
      return !(this-&gt;_value);
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator &amp;&amp; (const rtype &amp; rvalue) const
  {
      return this-&gt;_value &amp;&amp; rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator || (const rtype &amp; rvalue) const
  {
      return this-&gt;_value || rvalue;
  }
  
  // Bitwise operators
  
  template &lt;typename type&gt; inline auto arithmetic &lt;type&gt; ::  operator ~ () const
  {
      return ~(this-&gt;_value);
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator &amp; (const rtype &amp; rvalue) const
  {
      return this-&gt;_value &amp; rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator | (const rtype &amp; rvalue) const
  {
      return this-&gt;_value | rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator ^ (const rtype &amp; rvalue) const
  {
      return this-&gt;_value ^ rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator &lt;&lt; (const rtype &amp; rvalue) const
  {
      return this-&gt;_value &lt;&lt; rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator &gt;&gt; (const rtype &amp; rvalue) const
  {
      return this-&gt;_value &gt;&gt; rvalue;
  }
  
  // Compound assignment operators
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator += (const rtype &amp; rvalue)
  {
      return this-&gt;_value += rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator -= (const rtype &amp; rvalue)
  {
      return this-&gt;_value -= rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator *= (const rtype &amp; rvalue)
  {
      return this-&gt;_value *= rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator /= (const rtype &amp; rvalue)
  {
      return this-&gt;_value /= rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator %= (const rtype &amp; rvalue)
  {
      return this-&gt;_value %= rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator &amp;= (const rtype &amp; rvalue)
  {
      return this-&gt;_value &amp;= rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator |= (const rtype &amp; rvalue)
  {
      return this-&gt;_value |= rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator ^= (const rtype &amp; rvalue)
  {
      return this-&gt;_value ^= rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator &lt;&lt;= (const rtype &amp; rvalue)
  {
      return this-&gt;_value &lt;&lt;= rvalue;
  }
  
  template &lt;typename type&gt; template &lt;typename rtype, typename std :: enable_if &lt;__arithmetic :: __is_arithmetic_convertible &lt;rtype&gt; :: value&gt; :: type *&gt; inline auto arithmetic &lt;type&gt; ::  operator &gt;&gt;= (const rtype &amp; rvalue)
  {
      return this-&gt;_value &gt;&gt;= rvalue;
  }
  
  // Member and pointer operators
  
  template &lt;typename type&gt; inline type * arithmetic &lt;type&gt; :: operator &amp; ()
  {
      return &amp;(this-&gt;_value);
  }
  
  template &lt;typename type&gt; inline const type * arithmetic &lt;type&gt; :: operator &amp; () const
  {
      return &amp;(this-&gt;_value);
  }
  
  // Casting
  
  template &lt;typename type&gt; inline arithmetic &lt;type&gt; :: operator type &amp; ()
  {
      return this-&gt;_value;
  }
  
  template &lt;typename type&gt; inline arithmetic &lt;type&gt; :: operator const type &amp; () const
  {
      return this-&gt;_value;
  }
  </code></pre>
  
  <p>Which is basically just a very pedantic wrapper for arithmetic types. The wrapper has an arithmetic member called <code>_value</code>, then all the calls to any operator are forwarded down to <code>_value</code>, and there is a cast operator to the original arithmetic type.</p>
  
  <p>Now, I wonder, is there any circumstance in which, say, an <code>arithmetic &lt;int&gt;</code> will behave differently than an <code>int</code>? I can't seem to figure out any, but I thought I'd ask a more informed opinion.</p>
  
  <p>On the other hand, if this works as expected and <code>arithmetic &lt;int&gt;</code> behaves as an <code>int</code>, then why isn't this part of the standard? It looks quite trivial to implement and would allow us to extend arithmetic types as we please.</p>