C++中哪些运算符重载存在强制参数类型或返回类型?
Great question—this is a common point of confusion when diving into C++ operator overloading, since most operators follow conventions rather than hard rules, but a few have strict requirements. Let's break this down clearly:
1. Operators with Mandatory Parameter Types/Structure
These are cases where the C++ standard enforces specific parameter setups to distinguish behavior or meet language requirements:
Prefix vs. Suffix ++/--
You already touched on this, but let's formalize the mandatory rules:
- Prefix (
++obj): Can only take a single parameter (almost always a non-const reference to your class type, so you can modify the object in place). No dummy parameters allowed here.number& operator++(number& num) { num.a += 1; return num; // Returning the modified object is convention, not mandatory—but highly recommended } - Suffix (
obj++): Must include a second dummy parameter of typeint(you can even omit the parameter name, likeoperator++(int)). This is the only way the compiler can tell the suffix version apart from the prefix—you can't use any other type for this dummy (e.g.,doublewon't work). The dummy's value is never used, it's just a syntactic marker.number operator++(number& num, int) { number temp = num; num.a += 1; return temp; // Returning the original value is convention here }
operator[] (Array Subscript)
While the standard doesn't force a specific parameter type (you could technically use a std::string as an index if you wanted), it does require this operator to be overloaded as a member function (not a free function). Beyond that, the parameter type is up to you—though using integer types like size_t or int is the universal convention for array-like behavior.
2. Operators with Mandatory Return Types
There are a small handful of operators where the C++ standard strictly enforces the return type or behavior:
Conversion Operators
These are the operators like operator T() (used to convert your class object to type T). The return type is mandatorily T, and you don't even write the return type in the function signature—it's implied by the operator name. For example:
struct number { int a = 0; // Must return int (no explicit return type declared) operator int() const { return a; } };
If you try to return a different type here (like double instead of int), the compiler will throw an error immediately.
operator->
This operator must return either:
- A pointer type (e.g.,
int*,MyClass*), or - An object of a type that itself overloads
operator->(this is how smart pointers likestd::unique_ptrwork, enabling chained->calls).
Returning any other type (likeintorstd::string) will result in a compiler error, since the standard requires the result to support the->operation.
Honorable Mention: operator=
While the standard doesn't strictly force the return type, it's a non-negotiable convention to return a non-const reference to the object (to enable chained assignments like a = b = c). Technically you could return a different type, but this would break expected behavior and confuse other developers. That said, this is a convention, not a language mandate.
3. Operators with No Mandatory Rules (Like ==)
As you discovered, operators like operator==, operator+, operator-, etc., have no strict language-enforced return or parameter types. For example, you can make operator== return your number type instead of bool:
number operator==(const number& lhs, const number& rhs) { return {lhs.a == rhs.a ? 1 : 0}; }
This will compile, but it's strongly discouraged—it breaks the expected behavior of equality checks (used in if statements, loops, etc.), and the non-bool return type will trigger implicit conversions that can lead to bugs or confusing behavior. But syntactically, the C++ standard allows it.
内容的提问来源于stack exchange,提问作者Bartvbl

