2016-12-05 1 views
1

Gibt es Rechenaufwand durch die Implementierung von Klassenwrapper, um Typ-Sicherheit auf C primitiven Typen zu gewährleisten? Und wenn nicht, warum sind diese Wrapper nicht in der STL?C++ primitiver Typ Sicherheit

#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

Versuchen Sie es. Sie werden schnell herausfinden, warum dies nicht der Fall ist. –

+3

Warum ist int32 + int32 "sicher"? Tipp: Es ist nicht. –

+0

Es würde sehr schnell langweilig werden, immer zu werfen, wann immer Sie numerische Werbung brauchen (was eine ziemlich bequeme Sache ist) – StoryTeller

Antwort

0

Der Aufwand ist enorm, da jede einzelne Operation potenziell überlaufen kann und nur selten der Compiler in der Lage sein wird, Ihre Schecks zu optimieren. Das ist im Grunde, warum Range-checked Typen nicht in der STL sind. Ada wendet solche Überprüfungen an, und sie wurden von Anfang an in die Sprache eingebaut, es ist nicht etwas, das unmöglich oder von Natur aus eine schlechte Idee ist.

Aber wie andere gesagt haben, ist es nicht gut für C++. Wenn Sie es tun müssen, rate ich, dass alle Daten als Doppel gehalten werden und nicht über den Bereich +/- FTL_MAX hinausgehen dürfen, und FLT_EPSILON wird auf Null geklemmt. Alle Indizes gelten als int int und müssen sehr genau auf INT_MAX geklemmt werden.

+2

Sehen Sie im vorgeschlagenen Wrapper Bereichsüberprüfungen? –

Verwandte Themen