检测类型的等价性

detecting equivalence of typedefs

本文关键字:类型 检测      更新时间:2023-10-16

在我的应用程序中,我有一个类型负责(可能)涉及大数的计算,还有一个类型用于处理器之间的通信。

typedef MyBigIntegerClass bigInt;
typedef int smallInt;

通信部分与MyBigIntegerClass不兼容,因此在通信之前,例如bigint的向量必须转换为smallint。到目前为止,没有任何问题。

然而,对于大多数问题实例,使用MyBigIntegerClass是不必要的。事实上,即使是int32_t也是充分的。这就是为什么我允许像

这样的配置
typedef int32_t bigInt;
typedef int16_t smallInt;

对于计算来说,bigInt类型仍然足够大。这样做的问题是,smallInt必须不同于bigInt。

class Problematic
{
    public:
       Problematic(bigInt);
       Problematic(smallInt);
};

在该类中,构造函数或方法可以接受bigint型或smallint型参数。如果它们相同,则编译失败。

由于代码的其他用户可能想要调整所使用的类型,因此他们可能最终得到像

这样的配置
typedef int32_t bigInt;
typedef int32_t smallInt;

和编译以一种不明显的方式失败(至少对一些开发人员来说)。

处理这种情况的一种方法是static_assert(sizeof(bigInt) != sizeof(smallint), "bad config.."),但我实际上喜欢bigInt == smallInt的可能性。更改class Problematic的声明以允许类型等价的好方法是什么?

如果需要保留这两个构造函数,一个可能的解决方案是将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/获得关于实现操作符的有用指导)。