【问题标题】:Selecting the right equality operator when using templates使用模板时选择正确的相等运算符
【发布时间】:2011-05-25 04:18:52
【问题描述】:

我正在尝试编写一个 uint128_t 库 (http://stackoverflow.com/questions/6119306/operator-overloading-c-placement) 并且遇到了一个问题:我需要对不同类型的整数进行操作,例如 @ 987654321@。我已经编写了运算符重载,例如template <typename t> uint128_t operator^(T val)。我还需要能够做到uint128_t ^ uint128_t。但是,由于我的 uint128_t 使用 2 个 uint64_t 来存储值,我不能简单地将 uint128_t 用作 T。因此,我编写了 2 个不同的函数,一个以 T 作为参数类型,另一个以 uint128_t 作为类型。

问题在于编译器对标准 c++ int 类型和 uint128_t 都使用了 T val 版本。我如何让编译器区分它们?

编辑:我在链接的类中有这个代码:

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);

这两行都将使用顶部运算符。但是,由于 uint128_t 是 2 个部分,并且是一个对象,因此计算机会将 uint64_t 与一个类进行比较,而不是与一个值进行比较。如何强制计算机使用第二个 == 运算符?

【问题讨论】:

  • 一些示例代码会非常有用
  • 您确定在这两种情况下都使用顶级版本吗?在比较两个 uint128_t 时,C++ 的重载决议应该总是更喜欢确切的非模板函数而不是模板版本。
  • 这似乎是在做什么。我还在检查...
  • 好吧...它似乎不像我声称的那样使用相同的功能。

标签: c++ templates operator-overloading


【解决方案1】:

除了转换构造函数之外,您甚至不需要额外的重载。然后你只需编写处理 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

【讨论】:

    【解决方案2】:

    尝试将模板运算符从类中取出并使它们全局化,然后指定您需要的特定转换,即:

    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()));
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-26
      • 2021-10-19
      • 1970-01-01
      • 1970-01-01
      • 2020-01-03
      • 1970-01-01
      • 2017-02-08
      • 1970-01-01
      相关资源
      最近更新 更多