使用强制转换运算符和单参数构造函数重载类的运算符

时间:2013-01-17 18:52:06

标签: c++ operator-overloading typecast-operator

我有这样的代码

class Number
{
    int m_value;

public :
    Number(const int value) : 
        m_value(value)
    {
    }

    operator const int() const
    {
        return m_value;
    }

    int GetValue() const
    {
        return m_value;
    }
};

bool operator==(const Number& left, const Number& right)
{
    return left.GetValue() == right.GetValue();
}

class Integer
{
    int m_value;

public :
    Integer(const int value) : 
        m_value(value)
    {
    }

    operator const int() const
    {
        return m_value;
    }

    bool operator==(const Integer& right) const
    {
        return m_value == right.m_value;
    }

    bool operator==(const int right) const
    {
        return m_value == right;
    }

    int GetValue() const
    {
        return m_value;
    }
};

bool operator==(const int left, const Integer& right)
{
    return left == right.GetValue();
}

int main()
{
    Number n1 = 1;
    Number n2 = 1;
    int x3 = 1;

    n1 == n2;
    n1 == x3; // error C2666: 'operator ==' : 3 overloads have similar conversions
    x3 == n1; // error C2666: 'operator ==' : 2 overloads have similar conversions

    Integer i4 = 1;
    Integer i5 = 1;

    i4 == i5;
    i4 == x3;
    x3 == i4;

    return 0;
}

对于班级Number,我有两个错误,如上面的代码所示。对于班级Integer,一切正常。问题是,我想保留结果类单参数构造函数,强制转换操作符和相等操作(MyClass == intint == MyClassMyClass == MyClass),但我想只实现一个版本的班级operator==中的Number。我认为没有办法做到这一点。这是可能的,还是我必须在课程Integer中拥有所有三个实现?我知道为什么我会遇到这些错误,我只是不喜欢我的解决方案。

3 个答案:

答案 0 :(得分:2)

在课程Number中,您将转化运算符定义为int,您的构造函数允许将int转换为Number。因此,在比较Number nint x的相等性时,会产生歧义:编译器是否应为operator ==调用内置int并转换nint,还是应该选择您的运营商并将x转换为Number?两次转换都同样好,而且无法选择。

所以是的,你必须定义三个版本,或者添加一个模板运算符,它可以完全匹配所有参数的类型并显式转发给你的运算符,就像这个一样(但是你很可能想用一些{{1仅将其适用性限制为适当的enable_ifT):

U

答案 1 :(得分:0)

您只能将一个operator==定义为成员函数:

bool operator==(const int& right) const
{
    std::cout << "custom\n";
    return this->GetValue() == right;
}

然后,

  • n1==n2n2将转换为int并将使用自定义运算符。
  • n1 == n3:将使用自定义运算符
  • n3==n1:将使用内置运算符

注意,您希望operator== const能够比较常量Number

答案 2 :(得分:0)

在C ++ 11中,您可以明确operator int

另一种方法是使用SFINAE来制作适用于一个或多个== args的模板Number,但这是使用火箭筒杀死蚂蚁。