我具有三个功能,可用于同一事物,但适用于不同的伪参数类型:flip,flipLogical和flipInt。他们的代码实际上完全一样!还有另一个函数叫做flip3D,它仅用于真正的伪参数,它从其内部调用flip。这就是现在一切正常的方式:
function flip(data)
real, dimension(:,:), intent(in) :: data
real, dimension(:,:), allocatable :: flip
integer :: m, n, i
m = size(data,1)
n = size(data,2)
allocate(flip(m,n))
do i=1,m
flip(m-i+1,:) = data(i,:)
end do
end function flip
function flipLogical(data)
logical, dimension(:,:), intent(in) :: data
logical, dimension(:,:), allocatable :: flipLogical
integer :: m, n, i
m = size(data,1)
n = size(data,2)
allocate(flipLogical(m,n))
do i=1,m
flipLogical(m-i+1,:) = data(i,:)
end do
end function flipLogical
function flipInt(data)
integer, dimension(:,:), intent(in) :: data
integer, dimension(:,:), allocatable :: flipInt
integer :: m, n, i
m = size(data,1)
n = size(data,2)
allocate(flipInt(m,n))
do i=1,m
flipInt(m-i+1,:) = data(i,:)
end do
end function flipInt
function flip3D(data)
real, dimension(:,:,:), intent(in) :: data
real, dimension(:,:,:), allocatable :: flip3D
integer :: m, n, o, j
m = size(data, 1)
n = size(data, 2)
o = size(data, 3)
allocate(flip3D(n, m, o))
do j = 1, o
flip3D(:,:,j) = flip(data(:,:,j))
end do
end function flip3D
尽管这很好用,但是却很丑陋。我希望有一个多态函数flip,它适用于任何类型,并且我可以从flip3D调用它,以提供一个实变量作为伪参数。我正在尝试类似的事情:
function flip(data)
class(*), dimension(:,:), intent(in) :: data
class(*), dimension(:,:), allocatable :: flip
integer :: m, n, i
m = size(data,1)
n = size(data,2)
allocate(flip(m,n), mold=data)
do i=1,m
flip(m-i+1,:) = data(i,:)
end do
end function flip
但随后我收到错误消息
script.f90:698:7:
flip(m-i+1,:) = data(i,:) 1 Error: Nonallocatable variable must not be polymorphic in intrinsic assignment at (1) - check that there is a matching specific subroutine for '=' operator
script.f90:714:23:
flip3D(:,:,j) = flip(data(:,:,j)) 1 Error: Can't convert CLASS(*) to REAL(4) at (1)
答案 0 :(得分:1)
我可以通过模板实现通用功能,但是请注意
function flip(data)
class(*), dimension(:,:), intent(in) :: data
class(*), dimension(:,:), allocatable :: flip
integer :: i
flip = data([(i,i=m,1,-1)],:)
end function flip
用gfortran编译。
编辑:给定模板文件flip.i90
:
function Qflip(Qdata)
dimension Qdata(:,:)
intent(in) Qdata
dimension Qflip(size(Qdata,1),size(Qdata,2))
integer i
do i = 1, size(Qdata,1)
Qflip(size(Qdata,1)-i+1,:) = Qdata(i,:)
end do
end function Qflip
我们可以编译flip.f90
:
module real_mod
implicit real(Q)
private
public flip
interface flip
module procedure Qflip
end interface flip
contains
include 'flip.i90'
end module real_mod
module Logical_mod
implicit Logical(Q)
private
public flip
interface flip
module procedure Qflip
end interface flip
contains
include 'flip.i90'
end module Logical_mod
module Int_mod
implicit integer(Q)
private
public flip
interface flip
module procedure Qflip
end interface flip
contains
include 'flip.i90'
end module Int_mod
module flip_mod
use real_mod
use Logical_mod
use Int_mod
end module flip_mod
program flipmeoff
use flip_mod
implicit none
real :: R(3,3) = reshape([ &
1, 2, 3, &
4, 5, 6, &
7, 8, 9],shape(R),order=[2,1])
Logical :: L(3,3) = reshape([ &
.TRUE., .TRUE., .FALSE., &
.FALSE., .TRUE., .FALSE., &
.FALSE., .FALSE., .TRUE.],shape(L),order=[2,1])
integer :: I(3,3) = reshape([ &
1, 2, 3, &
4, 5, 6, &
7, 8, 9],shape(I),order=[2,1])
write(*,'(3(f3.1:1x))') transpose(R)
write(*,'()')
write(*,'(3(f3.1:1x))') transpose(flip(R))
write(*,'()')
write(*,'(3(L1:1x))') transpose(L)
write(*,'()')
write(*,'(3(L1:1x))') transpose(flip(L))
write(*,'()')
write(*,'(3(i1:1x))') transpose(I)
write(*,'()')
write(*,'(3(i1:1x))') transpose(flip(I))
end program flipmeoff
并产生输出:
1.0 2.0 3.0
4.0 5.0 6.0
7.0 8.0 9.0
7.0 8.0 9.0
4.0 5.0 6.0
1.0 2.0 3.0
T T F
F T F
F F T
F F T
F T F
T T F
1 2 3
4 5 6
7 8 9
7 8 9
4 5 6
1 2 3
不幸的是,Fortran不允许您像可以派生类型那样重命名内部类型。结果是可以与内部类型一起使用的模板文件必须使用implicit
键入。