14.9.3. Function Matching and Overloaded Operators

Image

Overloaded operators are overloaded functions. Normal function matching (§ 6.4, p. 233) is used to determine which operator—built-in or overloaded—to apply to a given expression. However, when an operator function is used in an expression, the set of candidate functions is broader than when we call a function using the call operator. If a has a class type, the expression a sym b might be

a.operatorsym (b); // a has operatorsym as a member function
operatorsym(a, b); // operatorsym is an ordinary function

Unlike ordinary function calls, we cannot use the form of the call to distinquish whether we’re calling a nonmember or a member function.


Exercises Section 14.9.2

Exercise 14.50: Show the possible class-type conversion sequences for the initializations of ex1 and ex2. Explain whether the initializations are legal or not.

struct LongDouble {
    LongDouble(double = 0.0);
    operator double();
    operator float();
};
LongDouble ldObj;
int ex1 = ldObj;
float ex2 = ldObj;

Exercise 14.51: Show the conversion sequences (if any) needed to call each version of calc and explain why the best viable function is selected.

void calc(int);
void calc(LongDouble);
double dval;
calc(dval); // which calc?


When we use an overloaded operator with an operand of class type, the candidate functions include ordinary nonmember versions of that operator, as well as the built-in versions of the operator. Moreover, if the left-hand operand has class type, the overloaded versions of the operator, if any, defined by that class are also included.

When we call a named function, member and nonmember functions with the same name do not overload one another. There is no overloading because the syntax we use to call a named function distinguishes between member and nonmember functions. When a call is through an object of a class type (or through a reference or pointer to such an object), then only the member functions of that class are considered. When we use an overloaded operator in an expression, there is nothing to indicate whether we’re using a member or nonmember function. Therefore, both member and nonmember versions must be considered.


Image Note

The set of candidate functions for an operator used in an expression can contain both nonmember and member functions.


As an example, we’ll define an addition operator for our SmallInt class:

class SmallInt {
    friend
    SmallInt operator+(const SmallInt&, const SmallInt&);
public:
    SmallInt(int = 0);                   // conversion from int
    operator int() const { return val; } // conversion to int
private:
    std::size_t val;
};

We can use this class to add two SmallInts, but we will run into ambiguity problems if we attempt to perform mixed-mode arithmetic:

SmallInt s1, s2;
SmallInt s3 = s1 + s2;  // uses overloaded operator+
int i = s3 + 0;         // error: ambiguous

The first addition uses the overloaded version of + that takes two SmallInt values. The second addition is ambiguous, because we can convert 0 to a SmallInt and use the SmallInt version of +, or convert s3 to int and use the built-in addition operator on ints.


Image Warning

Providing both conversion functions to an arithmetic type and overloaded operators for the same class type may lead to ambiguities between the overloaded operators and the built-in operators.



Exercises Section 14.9.3

Exercise 14.52: Which operator+, if any, is selected for each of the addition expressions? List the candidate functions, the viable functions, and the type conversions on the arguments for each viable function:

struct LongDouble {
    // member operator+ for illustration purposes; + is usually a nonmember
    LongDouble operator+(const SmallInt&);
    // other members as in § 14.9.2 (p. 587)
};
LongDouble operator+(LongDouble&, double);
SmallInt si;
LongDouble ld;
ld = si + ld;
ld = ld + si;

Exercise 14.53: Given the definition of SmallInt on page 588, determine whether the following addition expression is legal. If so, what addition operator is used? If not, how might you change the code to make it legal?

SmallInt s1;
double d = s1 + 3.14;


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset