在我的应用程序中,我有一个负责计算的类型(可能)涉及大数字和用于处理器之间通信的类型。
typedef MyBigIntegerClass bigInt;
typedef int smallInt;
通信部分与MyBigIntegerClass不兼容,因此在通信之前,例如bigInts的矢量,它必须转换为smallints。到目前为止,完全没问题。
但是,对于大多数问题实例,不需要使用MyBigIntegerClass。事实上,即使int32_t
也足够了。这就是我允许配置
typedef int32_t bigInt;
typedef int16_t smallInt;
bigInt类型对于计算内容仍然足够大。这个问题是,smallInt必须与bigInt不同。
class Problematic
{
public:
Problematic(bigInt);
Problematic(smallInt);
};
在这个类中,构造函数或方法可以使用bigInts或smallInts。如果它们相同,则编译失败。
由于代码的其他用户可能希望调整使用的类型,因此最终可能会使用
等配置typedef int32_t bigInt;
typedef int32_t smallInt;
并且编译失败(对于至少一些开发人员)非显而易见的方式。
处理此问题的一种方法是static_assert(sizeof(bigInt) != sizeof(smallint), "bad config..")
,但我实际上喜欢拥有bigInt == smallInt
的可能性。更改class Problematic
声明以允许类型等价的好方法是什么?
答案 0 :(得分:2)
如果希望保留两个构造函数,可能的解决方案是将int
类型包装在模板中,这意味着它们总是不同的类型,即使基础int
类型相同:
template <typename T>
struct big_int
{
T value;
};
template <typename T>
struct small_int
{
T value;
};
typedef big_int<long> bigInt;
typedef small_int<long> smallInt;
class Problematic
{
public:
Problematic(bigInt) {}
Problematic(smallInt) {}
};
在基础类型相同(http://ideone.com/KGz9Vk)时以及它们不相同时(http://ideone.com/Pt0XGS)进行编译。
要允许big_int<>
和small_int<>
表现为整数类型,需要实现运算符。例如:
template <typename T>
struct big_int
{
T value;
operator T() { return value; }
big_int& operator+=(big_int const& other)
{
value += other.value;
return *this;
}
template <typename U>
big_int& operator+=(U const& v)
{
value += v;
return *this;
}
big_int& operator++()
{
++value;
return *this;
}
big_int operator++(int)
{
big_int temp = *this;
++value;
return temp;
}
};
这并非详尽无遗(有关实施运营商的有用指导,请参阅http://herbsutter.com/2013/05/20/gotw-4-class-mechanics/)。例如,请参阅http://ideone.com/xlE2Mi。