Object-Oriented Fortran: Does Fortran support operator overloading?
TariqueIslam 2700046692 Visits (13811)
I will start with a simple example to describe the mechanism and will mention the related language rules at the end. Consider an application that processes points in three dimensions where a point is represented by the following derived type.
Consider that the application requires adding an offset of type real to each dimension of a point. Let us extend the '+' operator to perform the intended operation.
Step 1: Define the meaning of applying '+' on objects of type point_t and real:
- This translates to defining a function, say add_
Step 2: Indicate that the function add_offset_to_point will be used as '+' operation:
- This translates to providing a generic interface for the function add_offset_to_point and specifying OPERATOR in the generic specification.
INTERFACE OPERATOR (+)
Step 3: Using the newly defined operator the same way as an intrinsic '+' operator is used.
type(point_t) :: pt1, pt2, pt3
The compiler interprets "pt3 = pt1 + off" as "pt3 = add_
The following example consolidates the pieces from above into a complete program.
The program produces the following output.
> xlf2003 defined-op.f
Now, consider that the application needs to add (dimension wise) coordinates of two point_t type objects as shown below.
pt3 = pt1 + pt2
In order to support the new operation, we just need to define another function, say add_point_to_point, to perform the operation, and add the interface of add_point_to_point to the generic interface ('+') we created in Step 2.
INTERFACE OPERATOR (+)
The last step demonstrates how an operator can be extended to operate on multiple combinations of operand types. The combinations of operand types must be such that op1 + op2 resolves to a unique specific binding of ('+') in accordance with the language rules for generic interface.
For completeness, let us define a unary operator ".XCOORD." to retrieve the value of the x coordinate of a point. The interface and the new function are as follows.
INTERFACE OPERATOR (.XCOORD.)
Now that we have seen all the required steps, let us consider an alternative to Step 2. The generic interface of a defined-operator can be bound to a derived-type. For example, we could represent the points by the following type.
The difference from the previous method is that the compiler interprets "pt1 + pt2" as "pt1
I am going to conclude this article by mentioning the language rules that govern defined-operators.
R1) A defined-operator shall be unary or binary. All procedures specified in the generic interface corresponding to a unary (binary, respectively) intrinsic operator must be functions with one (two, respectively) arguments. In our example, both "add
R2) The dummy arguments of these function must be non optional, and have INTENT(IN) attribute.
R3) An extended intrinsic operator must operate on the same number of operands as the original intrinsic operator. Therefore, an extended '*' operator must be binary whereas an extended ".NOT." must be unary.
R4) When a function extends an intrinsic operation, at least one dummy argument must have a type, kind parameter, or rank that distinguish the extended operation from the intrinsic operation. In our example, the type of the dummy argument "op1" of function "add
R5) Relational operators have two forms. For example "<" has the same interpretation as ".LE.". Extending one form automatically extends both forms.