在 C++ 中重载不同类型
Overloading different types in C++
假设我们有以下 class:
class Rational { // Represents rational number. n=1/2=d for example.
public:
int n = 0;
int d = 1;
};
Rational x = Rational();
x.n = 1;
x.d = 2;
是否可以进行重载,使 3 * x
给出 3/2
而不是错误?
我老师说重载只发生在相同类型的对象之间,但是为什么我们可以在ostream
类型的cout
和Rational
类型的对象之间进行重载而不是 int
和 Rational
?
类型
你可以这样写
Rational operator *( const Rational &r, int x )
{
return { r.n * x, r.d };
}
Rational operator *( int x, const Rational &r )
{
return { r.n * x, r.d };
}
您可以为用户定义的类型重载运算符。对于二元运算符,至少有一个操作数必须是用户定义的类型。
来自 C++ 20 标准(12.4.2.3 表达式中的运算符)
2 If either operand has a type that is a class or an enumeration, a
user-defined operator function can be declared that implements this
operator or a user-defined conversion can be necessary to convert the
operand to a type that is appropriate for a built-in operator. In this
case, overload resolution is used to determine which operator function
or built-in operator is to be invoked to implement the operator.
Therefore, the operator notation is first transformed to the
equivalent function-call notation as summarized in Table 15 (where @
denotes one of the operators covered in the specified subclause).
However, the operands are sequenced in the order prescribed for the
built-in operator (7.6).
假设我们有以下 class:
class Rational { // Represents rational number. n=1/2=d for example.
public:
int n = 0;
int d = 1;
};
Rational x = Rational();
x.n = 1;
x.d = 2;
是否可以进行重载,使 3 * x
给出 3/2
而不是错误?
我老师说重载只发生在相同类型的对象之间,但是为什么我们可以在ostream
类型的cout
和Rational
类型的对象之间进行重载而不是 int
和 Rational
?
你可以这样写
Rational operator *( const Rational &r, int x )
{
return { r.n * x, r.d };
}
Rational operator *( int x, const Rational &r )
{
return { r.n * x, r.d };
}
您可以为用户定义的类型重载运算符。对于二元运算符,至少有一个操作数必须是用户定义的类型。
来自 C++ 20 标准(12.4.2.3 表达式中的运算符)
2 If either operand has a type that is a class or an enumeration, a user-defined operator function can be declared that implements this operator or a user-defined conversion can be necessary to convert the operand to a type that is appropriate for a built-in operator. In this case, overload resolution is used to determine which operator function or built-in operator is to be invoked to implement the operator. Therefore, the operator notation is first transformed to the equivalent function-call notation as summarized in Table 15 (where @ denotes one of the operators covered in the specified subclause). However, the operands are sequenced in the order prescribed for the built-in operator (7.6).