Fortran 命名运算符
Fortran named operator
我编写了一个派生类型并为其定义了一个命名运算符,如下所示:
module ModuleNamedOperator
implicit none
type TCoords
contains
procedure :: TCoordsFM
generic,public :: operator(.fm.) => TCoordsFM
end type
contains
type(TCoords) function TCoordsFM(self,IVal) result(this)
class(TCoords),intent(in) :: self
integer(4),intent(in) :: IVal
this=self
write(*,'(I0)') "IVal:",IVal
end function TCoordsFM
end module ModuleNamedOperator
当我尝试在以下代码中使用它时,发生了一些奇怪的事情:
program test
use ModuleNamedOperator
implicit none
type(TCoords) :: a
integer(4) :: i
i=1
a=a .fm. 1 ! Case 1, valid
a=a .fm. i ! Case 2, valid
a=a .fm. 1 .fm. i ! Case 3, invalid
a=a .fm. i .fm. 1 ! Case 4, valid
a=a .fm. 1 .fm. 1 ! Case 5, valid
a=a .fm. i .fm. i ! Case 6, invalid
end program test
在案例 3 和案例 6 中,代码无效。似乎如果运算符.fm 的第二个参数。是一个变量或一个命名常量,那么就会发生错误。那么这些案件是怎么回事呢?还有出路吗?如果重要的话,编译器是 ifort_2013_sp1.3.174。
编译器给出以下错误消息:
TestNamedOperator.f90(25): error #6866: Dotted string neither a defined operator nor a structure component [FM]
a=a .fm. 1 .fm. i
--------------^
TestNamedOperator.f90(28): error #6866: Dotted string neither a defined operator nor a structure component [FM]
a=a .fm. i .fm. i
--------------^
TestNamedOperator.f90(25): error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.
a=a .fm. 1 .fm. i
-------------^
TestNamedOperator.f90(28): error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.
a=a .fm. i .fm. i
-------------^
compilation aborted for TestNamedOperator.f90 (code 1)
我认为您遇到了 ifort
编译器错误,请参阅 here。将 write
语句更改为 write(*,'(A,I0)') "IVal:",IVal
时,您的代码可以使用 gfortran
正常编译。
对于 ifort
,显式调用函数有帮助:
program test
use ModuleNamedOperator
implicit none
type(TCoords) :: a
integer(4) :: i
i=1
a=a .fm. 1 ! Case 1, valid
a=a .fm. i ! Case 2, valid
a=TCoordsFM((a .fm. 1), i) ! Case 3, valid
a=TCoordsFM((a .fm. i), 1) ! Case 4, valid
a=TCoordsFM((a .fm. 1), 1) ! Case 5, valid
a=TCoordsFM((a .fm. i), i) ! Case 6, valid
end program test
我编写了一个派生类型并为其定义了一个命名运算符,如下所示:
module ModuleNamedOperator
implicit none
type TCoords
contains
procedure :: TCoordsFM
generic,public :: operator(.fm.) => TCoordsFM
end type
contains
type(TCoords) function TCoordsFM(self,IVal) result(this)
class(TCoords),intent(in) :: self
integer(4),intent(in) :: IVal
this=self
write(*,'(I0)') "IVal:",IVal
end function TCoordsFM
end module ModuleNamedOperator
当我尝试在以下代码中使用它时,发生了一些奇怪的事情:
program test
use ModuleNamedOperator
implicit none
type(TCoords) :: a
integer(4) :: i
i=1
a=a .fm. 1 ! Case 1, valid
a=a .fm. i ! Case 2, valid
a=a .fm. 1 .fm. i ! Case 3, invalid
a=a .fm. i .fm. 1 ! Case 4, valid
a=a .fm. 1 .fm. 1 ! Case 5, valid
a=a .fm. i .fm. i ! Case 6, invalid
end program test
在案例 3 和案例 6 中,代码无效。似乎如果运算符.fm 的第二个参数。是一个变量或一个命名常量,那么就会发生错误。那么这些案件是怎么回事呢?还有出路吗?如果重要的话,编译器是 ifort_2013_sp1.3.174。 编译器给出以下错误消息:
TestNamedOperator.f90(25): error #6866: Dotted string neither a defined operator nor a structure component [FM]
a=a .fm. 1 .fm. i
--------------^
TestNamedOperator.f90(28): error #6866: Dotted string neither a defined operator nor a structure component [FM]
a=a .fm. i .fm. i
--------------^
TestNamedOperator.f90(25): error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.
a=a .fm. 1 .fm. i
-------------^
TestNamedOperator.f90(28): error #6303: The assignment operation or the binary expression operation is invalid for the data types of the two operands.
a=a .fm. i .fm. i
-------------^
compilation aborted for TestNamedOperator.f90 (code 1)
我认为您遇到了 ifort
编译器错误,请参阅 here。将 write
语句更改为 write(*,'(A,I0)') "IVal:",IVal
时,您的代码可以使用 gfortran
正常编译。
对于 ifort
,显式调用函数有帮助:
program test
use ModuleNamedOperator
implicit none
type(TCoords) :: a
integer(4) :: i
i=1
a=a .fm. 1 ! Case 1, valid
a=a .fm. i ! Case 2, valid
a=TCoordsFM((a .fm. 1), i) ! Case 3, valid
a=TCoordsFM((a .fm. i), 1) ! Case 4, valid
a=TCoordsFM((a .fm. 1), 1) ! Case 5, valid
a=TCoordsFM((a .fm. i), i) ! Case 6, valid
end program test