gpt4 book ai didi

c++ - 转换逻辑的目标是什么类型?

转载 作者:IT老高 更新时间:2023-10-28 22:17:42 27 4
gpt4 key购买 nike

我不明白为什么在下面的代码中表达式 C c3 = 5 + c;虽然 5 可以像前面的语句一样转换为 C 类型,但不会被编译。

#include <iostream>

class C
{
int m_value;
public:
C(int value): m_value(value) {} ;

int get_value() { return m_value; } ;

C operator+(C rhs) { return C(rhs.m_value+m_value); }
};

int main()
{
C c = 10;
C c2 = c + 5; // Works fine. 5 is converted to type C and the operator + is called
C c3 = 5 + c; // Not working: compiler error. Question: Why is 5 not converted to type C??

std::cout << c.get_value() << std::endl; // output 10
std::cout << c2.get_value() << std::endl; // output 15

}



最佳答案

因为如果 overload operator作为类的成员函数,它只能在该类的对象用作左操作数时调用。 (并且左操作数成为要调用的成员函数的隐式 *this 对象。)

Binary operators are typically implemented as non-members to maintain symmetry (for example, when adding a complex number and an integer, if operator+ is a member function of the complex type, then only complex+integer would compile, and not integer+complex).

根据标准,[over.match.oper]/3

(强调我的)

For a unary operator @ with an operand of a type whose cv-unqualified version is T1, and for a binary operator @ with a left operand of a type whose cv-unqualified version is T1 and a right operand of a type whose cv-unqualified version is T2, four sets of candidate functions, designated member candidates, non-member candidates, built-in candidates, and rewritten candidates, are constructed as follows:

  • (3.1) If T1 is a complete class type or a class currently being defined, the set of member candidates is the result of the qualified lookup of T1::operator@ ([over.call.func]); otherwise, the set of member candidates is empty.

也就是说,如果左操作数的类型不是类类型,则候选成员集合为空;不会考虑重载的运算符(作为成员函数)。

您可以将其作为非成员函数重载,以允许左右操作数的隐式转换。

C operator+(C lhs, C rhs) { return C(lhs.get_value() + rhs.get_value()); }

那么 c + 55 + c 都可以正常工作。

LIVE

顺便说一句:这将导致一个临时数组对象被构造(从intC)以调用非成员函数;如果您关心这一点,您可以添加所有三个可能的重载,如下所示。另请注意,这是一个权衡问题。

C operator+(C lhs, C rhs) { return C(lhs.get_value() + rhs.get_value()); }
C operator+(C lhs, int rhs) { return C(lhs.get_value() + rhs); }
C operator+(int lhs, C rhs) { return C(lhs + rhs.get_value()); }

还有 here '是关于何时使用普通、 friend 或成员函数重载的一些建议

In most cases, the language leaves it up to you to determine whether you want to use the normal/friend or member function version of the overload. However, one of the two is usually a better choice than the other.

When dealing with binary operators that don’t modify the left operand (e.g. operator+), the normal or friend function version is typically preferred, because it works for all parameter types (even when the left operand isn’t a class object, or is a class that is not modifiable). The normal or friend function version has the added benefit of “symmetry”, as all operands become explicit parameters (instead of the left operand becoming *this and the right operand becoming an explicit parameter).

When dealing with binary operators that do modify the left operand (e.g. operator+=), the member function version is typically preferred. In these cases, the leftmost operand will always be a class type, and having the object being modified become the one pointed to by *this is natural. Because the rightmost operand becomes an explicit parameter, there’s no confusion over who is getting modified and who is getting evaluated.

关于c++ - 转换逻辑的目标是什么类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54666628/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com