C++ C++;原始类型安全

C++ C++;原始类型安全,c++,type-safety,C++,Type Safety,通过实现类包装器来确保C基元类型的类型安全,是否有任何计算开销?如果没有,为什么那些包装器不在STL中 #include <iostream> template< typename T > class Safe { template<typename K> friend std::ostream& operator << (std::ostream&, const Safe<K>& ); pu

通过实现类包装器来确保C基元类型的类型安全,是否有任何计算开销?如果没有,为什么那些包装器不在STL中

#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;
}
#包括
模板
班级安全
{
模板
friend std::ostream&运算符m_值+其他m_值);
}
模板
内联安全::运算符-(常量安全和其他)常量
{
返回保险箱(此->m_值-其他m_值);
}
模板
内联安全::运算符*(常量安全和其他)常量
{
返回保险箱(此->m_值*其他m_值);
}
模板
内联安全::运算符/(常量安全和其他)常量
{
返回保险箱(此->m_值/其他m_值);
}
模板
内联安全::运算符%(常量安全和其他)常量
{
返回保险箱(此->m_值%其他m_值);
}
模板

内联std::ostream&operator开销很大,因为每个操作都可能溢出,而且编译器很少能够优化您的检出。这就是为什么范围检查类型不在STL中的基本原因。Ada确实应用了这样的检查,它们从一开始就被构建到语言中,这不是不可能的事情,也不是天生的坏主意


但是正如其他人所说的,这不是一个适合C++的好方法。如果您必须这样做,我建议所有数据都作为双倍保存,不允许超出+/-FTL_MAX的范围,并且FLT_EPSILON被钳制为零。所有索引都作为带符号的int保存,在钳制到int_MAX时要非常小心。

开销很大,因为每个操作都可能溢出,编译器很少能够优化您的签出。这就是为什么范围检查类型不在STL中的基本原因。Ada确实应用了这样的检查,它们从一开始就被构建到语言中,这不是不可能的事情,也不是天生的坏主意


但是正如其他人所说的,这不是一个适合C++的好方法。如果您必须这样做,我建议所有数据都作为双倍保存,不允许超出+/-FTL_MAX的范围,并且FLT_EPSILON被钳制为零。所有索引都作为带符号的int保存,在夹紧到int_MAX时要非常小心。

试试看。您将很快发现为什么这是一个非初学者。为什么int32+int32“安全”?提示:不是。我敢打赌没有间接费用。但通常最好的方法是自己测试。@StoryTeller One可以在安全的情况下进行整数提升(即,如果在64位中添加一个32位的a,则64位可以进行32位的提升),Robert Ramey建议进行提升。他也给了我一个机会,试试看。您将很快发现为什么这是一个非初学者。为什么int32+int32“安全”?提示:不是。我敢打赌没有间接费用。但通常最好的方法是自己测试。@StoryTeller One可以在安全的情况下进行整数提升(即,如果在64位中添加一个32位的a,则64位可以进行32位的提升),Robert Ramey建议进行提升。他还给出了一个答案。你在提议的包装中看到任何范围检查吗?你在提议的包装中看到任何范围检查吗?