Это дополнительный вопрос из темы, которую я начал здесь здесь.
По сути, я хочу добиться определения отложенного типа, который автоматически назначает примитивные типы (действительное, целое, символьное и логическое). Вы можете увидеть рабочий пример при переходе по вышеуказанной ссылке, и он компилируется с gcc version 7.3.0
и ifort version 18.0.0
.
Я теперь расширил код вДля того, чтобы «использовать» отложенный тип данных, не зная, какой тип примитива назначен.Это работает путем переопределения основных операторов.Для простоты я включил только оператор +
в следующем примере.Пример работает и компилируется с gfortran , но выдает ошибку при компиляции с ifort :
Ошибка # 6303: Операция присваивания или двоичное выражениеоперация недопустима для типов данных двух операндов.[PLUS_FUNC_CLASS] c% i = a% i + b% i
Кто-нибудь знает, в чем здесь проблема?Я уже погуглил ошибку, но не смог выяснить, что я делаю неправильно.
NOTE
, чтобы соответствовать точности, я использовал следующую компиляцию флаги
ifort -r8 -i8 tst.f90
gfortran -fdefault-real-8 -fdefault-integer-8 -fdefault-double-8 tst.f90
Вот пример кода:
module DervType
implicit none
type, public :: mytype
real :: r
integer :: i
character(len=:), allocatable :: c
logical :: l
end type
interface assignment(=)
module procedure equal_func_class
end interface
interface operator(+)
module procedure plus_func_class
end interface
contains
subroutine equal_func_class(a,b)
type(mytype), intent(out):: a
class(*), intent(in) :: b
select type (b)
type is (mytype)
print *, "is mytype"
if ( .not. a%r == b%r ) a%r = b%r !! <-- ugly, but necessary not to end up in an endless loop when reassigning mytype (only testing and assigning real here)
type is (real)
print *, "is real"
a%r = b
type is (integer)
print *, "is int"
a%i = b
type is (character(len=*))
print *, "is char"
a%c = b
type is (logical)
print *, "is logical"
a%l = b
end select
return
end subroutine equal_func_class
recursive function plus_func_class(a,b) result(c)
class(*), intent(in) :: a
class(*), intent(in) :: b
type(mytype) :: c
select type (a)
type is (mytype)
print *, "left side is mytype"
!! -------------------------------
!! only testing one case here and only real operations are
!! taken care of!
!! -------------------------------
select type (b)
type is (mytype)
print *, "right side is mytype"
c%i = a%i + b%i !! <-- this is where ifort throws the error
c%r = a%r + b%r !! <-- this is where ifort throws the error
type is (real)
print *, "right side is real", a%r
c = a%r + b
end select
!! do similar logic when the operands changing sides
type is (real)
print *, "left side is real"
end select
!c = 1.
return
end function plus_func_class
end module DervType
program TestType
use DervType
implicit none
type(mytype) :: test, test2, res, res2
real, parameter :: tt = 2.
test = 1.
test = 1
test = "Hey Tapir"
test = .true.
test2 = 2.
test = test2
print *, "test = ", test%r
res = test + 1.0
res2 = test + tt
print *, "Calculation 1 (real) : ", res%r
print *, "Calculation 2 (real) : ", res2%r
end program TestType
При компиляции с gfortran
и при запуске программы это дает следующий вывод:
is real
is int
is char
is logical
is real
is mytype
test = 2.0000000000000000
left side is mytype
right side is real 2.0000000000000000
is real
is mytype
left side is mytype
right side is real 2.0000000000000000
is real
is mytype
Calculation 1 (real) : 3.0000000000000000
Calculation 2 (real) : 4.0000000000000000