4

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

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以允许类型等价的好方法是什么?

4

1 回答 1

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

于 2013-05-22T10:30:58.043 回答