2016-12-05 24 views
1

Cプリミティブ型の型安全性を保証するためにクラスラッパーを実装することによって計算上のオーバーヘッドはありますか?そして、そうでない場合、そのラッパーがSTLにないのはなぜですか?C++プリミティブ型の安全性

#include <iostream> 

template< typename T > 
class Safe 
{ 
    template<typename K> 
    friend std::ostream& operator << (std::ostream&, const Safe<K>&); 

public: 

    using Type = T; 

    Safe() = default; 

    explicit Safe(const T& value) : m_value(value){} 

    Safe<T> operator +(const Safe<T>& other) const; 
    Safe<T> operator -(const Safe<T>& other) const; 
    Safe<T> operator *(const Safe<T>& other) const; 
    Safe<T> operator /(const Safe<T>& other) const; 
    Safe<T> operator %(const Safe<T>& other) const; 

private: 
    T m_value; 
}; 

template<typename T> 
inline Safe<T> Safe<T>::operator +(const Safe<T>& other) const 
{ 
    return Safe<T>(this->m_value + other.m_value); 
} 

template<typename T> 
inline Safe<T> Safe<T>::operator -(const Safe<T>& other) const 
{ 
    return Safe<T>(this->m_value - other.m_value); 
} 

template<typename T> 
inline Safe<T> Safe<T>::operator *(const Safe<T>& other) const 
{ 
    return Safe<T>(this->m_value * other.m_value); 
} 

template<typename T> 
inline Safe<T> Safe<T>::operator /(const Safe<T>& other) const 
{ 
    return Safe<T>(this->m_value/other.m_value); 
} 

template<typename T> 
inline Safe<T> Safe<T>::operator %(const Safe<T>& other) const 
{ 
    return Safe<T>(this->m_value % other.m_value); 
} 

template<typename T> 
inline std::ostream& operator << (std::ostream& os, const Safe<T>& number) 
{ 
    return os << number.m_value; 
} 

using Int8 = Safe<std::int8_t>; 
using Int16 = Safe<std::int16_t>; 
using Int32 = Safe<std::int32_t>; 
using Int64 = Safe<std::int64_t>; 

using UInt8 = Safe<std::uint8_t>; 
using UInt16 = Safe<std::uint16_t>; 
using UInt32 = Safe<std::uint32_t>; 
using UInt64 = Safe<std::uint64_t>; 

using Int = Safe<signed int>; 
using UInt = Safe<unsigned int>; 

int main(int, char *[]) 
{ 
    Int32 a(5); 
    Int32 b(2); 
    Int64 ehi(5); 
    Int64 bee(2); 

    const auto c = a + b; 
    const auto see = ehi + bee; 

    /* will not compile: */ 
    /* const auto result = a + bee; */ 

    std::cout << c << std::endl; 
    std::cout << see << std::endl; 

    return 0; 
} 
+2

お試しください。なぜこれが初心者でないのかをすぐに知ることができます。 –

+3

なぜint32 + int32が "安全"ですか?ヒント:そうではありません。 –

+0

数字の宣伝が必要なときはいつも、いつもキャストするのが非常に面倒になるでしょう(これはかなり便利です) – StoryTeller

答えて

0

1回の操作でオーバーフローが発生する可能性があり、コンパイラーがチェックアウトを最適化できることはほとんどないため、オーバーヘッドは大量です。これは、基本的にレンジチェック型がSTLにない理由です。 Adaはそのような小切手を適用し、最初から言語に組み込まれています。不可能でも本質的に悪い考えでもありません。

しかし、他の人が言っているように、それはC++にはあまり適していません。もしあなたがそれをしなければならないならば、私はすべてのデータがdouble型として保持され、+/- FTL_MAXの範囲を越えることは許されず、FLT_EPSILONはゼロにクランプされることを勧めます。すべてのインデックスはsigned intとして保持され、INT_MAXにクランプする際には非常に注意が必要です。

+2

提案されているラッパーに範囲チェックがありますか? –