преобразование шаблона - PullRequest
5 голосов
/ 11 августа 2011

У меня есть два класса int_t, uint_t как тип со знаком и тип без знака:

template <typename lo_t> struct uint_t;

template <typename hi_t, typename lo_t>
struct int_t
{
    lo_t lo;
    hi_t hi;

    int_t() : hi(0), lo(0) {}
    int_t(int value) : lo(value), hi(value<0? -1: 0) {}
    int_t(unsigned value) : lo(value), hi(0) {}

    int_t(const uint_t<lo_t>&);

    //template<typename ty_a, typename ty_b> int_t(const int_t<ty_a, ty_b>&);
};

template <typename hi_lo>
struct uint_t
{
    hi_lo lo, hi;

    uint_t() : lo(0), hi(0) {}
    uint_t(int value) : lo(value), hi(value<0? -1: 0) {}
    uint_t(unsigned value) : lo(value), hi(0) {}

    template<typename hi_t>
    uint_t(const int_t<hi_t, hi_lo>& value) : hi(value.hi), lo(value.lo) {}
};

template <typename hi_t, typename lo_t>
int_t<hi_t, lo_t>::int_t(const uint_t<lo_t>& value) : hi(value.hi), lo(value.lo)
{}

Поскольку я хочу, чтобы они работали так же, как встроенные типы, я определил оператор преобразования из одного в другойпоэтому я могу написать код, подобный следующему, и все еще работает:

typedef  int_t<int, unsigned>  int64;
typedef uint_t<unsigned>      uint64;

int64  a = 1000;
uint64 b = a;

uint64 x = 512;
 int64 y = x;

Теперь единственной оставшейся проблемой является преобразование типа int_t с более высокой или более низкой точностью в другой, поэтому я объявил конструктор с комментариями для этогоно я не знаю, что в нем написать?

Вот пример, который я использовал для проверки результата этого конструктора:

typedef  int_t<int, unsigned>  int64;
typedef uint_t<unsigned>      uint64;

typedef  int_t<int64, uint64> int128;
typedef uint_t<uint64>       uint128;

int64 a = 1024;
int128 b = a;

int128 x = 100;
int64 y = x;

Ответы [ 2 ]

1 голос
/ 11 августа 2011

Я понял ответ для Little and Big Endians:

template<typename ty_a, typename ty_b>
int_t(const int_t<ty_a, ty_b>& value)
{
    *this = value < 0? -1: 0;

#ifdef BIG_ENDIAN
        if (sizeof(*this) < sizeof(value))
            *this = *((int_t*)&value.lo + (sizeof(value.lo)/sizeof(*this) - 1));
        else
            *((int_t<ty_a, ty_b>*)&hi + sizeof(*this)/sizeof(value) - 1) = value;
#else
        if (sizeof(*this) < sizeof(value))
            *this = *(int_t*)&value;
        else
            *(int_t<ty_a, ty_b>*)&lo = value;
#endif
}

запомните требуемый ответ operator== и operator<, которые должны быть определены для int_t

1 голос
/ 11 августа 2011

Вы должны определить, что вы хотите, чтобы они делали.Для беззнаковых данных легко увеличить размер, вы просто устанавливаете старшие биты в 0 и копируете младшие биты из операнда.Для подписи вы можете захотеть подписать-расширить операнд.

Для сокращения вы также должны решить, что вы хотите сделать.Вы хотите бросить, если значение не подходит?Скорее всего, вы просто хотите выбросить все старшие биты и сохранить их в доступном месте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...