2

我有这样的代码

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 == int, int == MyClass, MyClass == MyClass),但我只想operator==在 class 中实现 as 的一个版本Number。我看不出有什么方法可以做到这一点。这是否可能,或者我必须在课堂上拥有所有三个实现Integer?我知道为什么会出现这些错误,我只是不喜欢我拥有的解决方案。

4

3 回答 3

2

在类Number中,您定义一个转换运算符 toint并且您的构造函数允许将 a 转换int为 a Number。因此,当比较 aNumber n和 anint x是否相等时,会产生歧义:编译器应该调用内置的operator ==for ints 并转换n为 an int,还是应该选择您的运算符并转换x为 a Number?两种转换都一样好,它不能选择一个。

所以是的,你必须定义三个版本,或者添加一个模板运算符,它可以完美匹配所有参数的类型并显式地转发给你的运算符,比如这个(但你很可能想用一些enable_if来保护它,以限制它的适用性适当的TU):

template<typename T, typename U> // beware: this will match anything. to be constrained
bool operator == (T n, U const& u)
{
    return (Number(n) == Number(u));
}
于 2013-01-17T19:00:10.380 回答
0

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

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

然后,

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

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

于 2013-01-17T19:09:24.257 回答
0

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

另一种方法是使用 SFINAE 来创建一个==适用于一个或多个Number参数的模板,但这是使用火箭筒杀死一只蚂蚁。

于 2013-01-17T19:14:53.623 回答