C++ C++;原始类型安全
通过实现类包装器来确保C基元类型的类型安全,是否有任何计算开销?如果没有,为什么那些包装器不在STL中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
#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建议进行提升。他还给出了一个答案。你在提议的包装中看到任何范围检查吗?你在提议的包装中看到任何范围检查吗?