- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Consider the following toy example:
module test_module
implicit none
type :: myint
integer :: i = 0
contains
generic :: assignment(=) => int_to_myint
procedure :: int_to_myint
end type myint
contains
subroutine int_to_myint(me,i) !myint = integer assignment
implicit none
class(myint),intent(inout) :: me
integer,intent(in) :: i
me%i = i
end subroutine int_to_myint
end module test_module
The type(myint)=integer assignment works great. My question is this: is it possible to have the reverse assignment (integer=type(myint)) work as well? This would be like overloading the assignment operator for the integer type, I guess? Is such a thing possible?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jacob Williams wrote:
...
The type(myint)=integer assignment works great. My question is this: is it possible to have the reverse assignment (integer=type(myint)) work as well? This would be like overloading the assignment operator for the integer type, I guess? Is such a thing possible?
Yes, at some price. The generic assignment overload needs to be unambiguous, so one needs to come up with a scheme to distinguish from your myint_to_int procedure. You can do so using the unlimited polymorphic object option as shown below. "Casting" the unlimited polymorphic object to an integer frequently in a compute-intensive environment may introduce a compute cost, so one has to weigh it against the benefits:
module test_module
implicit none
type :: myint
integer :: i = 0
contains
generic :: assignment(=) => int_to_myint, myint_to_int
procedure, pass(me) :: int_to_myint
procedure, pass(me) :: myint_to_int
end type myint
contains
subroutine int_to_myint(me, i) !myint = integer assignment
implicit none
class(myint), intent(inout) :: me
integer, intent(in) :: i
me%i = i
end subroutine int_to_myint
subroutine myint_to_int(i, me) !integer = myint assignment
implicit none
class(*), intent(inout) :: i
class(myint), intent(in) :: me
!.. process based on input type
select type (i)
type is (integer)
i = me%i
class default
!.. insert some error handling here
return
end select
end subroutine myint_to_int
end module test_module
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Using class(*) as the output argument makes the "casting" assignment universally applicable at compile time, but issues with mismatches become a runtime issue. If you only want to support assignment to integer, just declare the i argument of myint_to_int as type integer, an unsupported type on the left hand side of an assignment is then identified at compile time and the runtime overhead of the SELECT TYPE construct is removed.
subroutine myint_to_int(i, me) !integer = myint assignment
integer, intent(out) :: i
class(myint), intent(in) :: me
i = me%i
end subroutine myint_to_int
If you want to support other types on the left hand side, just add additional specific procedures with the dummy argument for the left hand side declared appropriately. Alternatively, consider a type bound operator or function that extracts the numeric value as an integer.
Ambiguity restrictions on specific procedures in the generic interface for ASSIGNMENT(=) only consider position, the general requirements on the interfaces of such specific procedures and the nature in which that generic is referenced removes the need for consideration of the other aspects that might otherwise make a generic reference ambiguous.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Now that is interesting. I always thought that the first dummy argument of a type bound procedure with the pass attribute had to be the class where it was contained. I didn't know it was allowed to put something before it.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page