Выбор правильного оператора равенства при использовании шаблонов - PullRequest
1 голос
/ 25 мая 2011

я пытаюсь написать библиотеку uint128_t (/4934578/peregruzka-operatorov-s-razmescheniya), и я столкнулся с трудностями: мне нужно работать с различными типами целых чисел, такими как uint128_t ^ uint64_t. Я написал перегрузки операторов, такие как template <typename t> uint128_t operator^(T val). Я также нужно иметь возможность делать uint128_t ^ uint128_t. однако, так как мой uint128_t использует 2 uint64_t s для хранения значений, я не могу просто использовать uint128_t как T. таким образом, я написал 2 разные функции, одну с T в качестве типа аргумента и другой с типом uint128_t.

проблема в том, что компилятор использует версию T val как для стандартных типов c ++ int, так и для uint128_t. как мне заставить компилятор различать их?

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

template <typename T>
bool operator==(T val){
    return (LOWER == (uint64_t) val);
}

bool operator==(uint128_t val){
    return ((UPPER == val.upper()) && (LOWER == val.lower()));
}

если я сделаю

uint128_t a(5), b(123, 45);
uint64_t c = 6;

(a == c);
(a == b);

обе строки будут использовать оператор top. однако, поскольку uint128_t состоит из 2 частей и является объектом, компьютер будет сравнивать uint64_t с классом, а не со значением. как заставить компьютер использовать второй оператор ==?

Ответы [ 2 ]

1 голос
/ 25 мая 2011

Попробуйте удалить операторы шаблонов из класса и сделать их глобальными, а затем указать нужные вам преобразования, т. Е.

template<typename T>
bool operator==(uint128_t v1, T v2)
{
    return (v1.lower() == (uint64_t) v2);
}

template<>
bool operator==(uint128_t v1, uint128_t v2)
{
    return ((v1.upper() == v2.upper()) && (v1.lower() == v2.lower()));
}
1 голос
/ 25 мая 2011

Вам даже не понадобятся дополнительные перегрузки для чего-либо, кроме конструкторов преобразования. Затем вы просто пишете операторы, которые обрабатывают uint128_t, и если вы попытаетесь передать другой конвертируемый тип, такой как int, он будет конвертирован с помощью конструктора преобразования, то будет вызван соответствующий оператор.

Смотрите, это работает:

#include <cstdint>
#include <iostream>

class uint128_t{
    private:
        uint64_t UPPER, LOWER;

    public:
    // constructors
        uint128_t(){
            UPPER = 0;
            LOWER = 0;
        }

        template <typename T>
        uint128_t(T val){
            UPPER = 0;
            LOWER = (uint64_t) val;
        }

        template <typename S, typename T>
        uint128_t(const S & upper_val, const T & lower_val){
            UPPER = (uint64_t) upper_val;
            LOWER = (uint64_t) lower_val;
        }       

        uint64_t upper() const{
            return UPPER;
        }

        uint64_t lower() const{
            return LOWER;
        }

        uint128_t & operator+=(const uint128_t & rhs)
        {
            uint64_t old_lower = LOWER;
            LOWER += rhs.LOWER;
            if(LOWER < old_lower)
                ++UPPER;
            UPPER += rhs.UPPER;
            return *this;
        }
};

bool operator==(const uint128_t & lhs, const uint128_t & rhs){
    return ((lhs.upper() == rhs.upper()) && (lhs.lower() == rhs.lower()));
}

int main()
{
    uint128_t v(25);
    v += 25;
    int c = 50;
    if(v == c)
        std::cout << "Good";
    if(v == c + 1)
        std::cout << "Bad";
}

http://ideone.com/BEq03

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