事实上,我想问的不是解决问题,而是要变得更有技巧。
假设我们有一个类型A,例如:
Type A
private
(some variant)
contains
(some procedures)
generic::f=>....
! we assume the inteface is f(input)
! real or integer or complex :: input
endtype
其中f
包含许多子例程。
现在我有另一种类型B
,其中使用了A
。
Type B
private
type(A)::oA
...
contains
f2
! we assume the interface is f2(otherinput,input)
! real :: otherinput
! real or integer or complex :: input
end type
现在我想定义将调用f2
的子例程f
。除了已知类型otherinput
之外,我们还有一个多种类型input
(我不确定我的陈述是否正确,但无论如何)。
突然我意识到我需要根据f2_1,f2_2,...
的不同类型定义很多子例程input
。但这是愚蠢的,因为f
已经考虑过这类事情。如何避免这种烦恼?
答案 0 :(得分:0)
虽然不是很优雅,但如果通过f
接收参数“input”并明确选择其类型来调用泛型函数class(*)
怎么样?例如,
module test_m
implicit none
type A_t
contains
procedure :: f_int
procedure :: f_real
generic :: f => f_int, f_real
endtype
type B_t
type(A_t) :: A
contains
procedure :: g
endtype
contains
subroutine f_int( me, n )
class(A_t) :: me
integer :: n
print *, "f_int : ", n
endsubroutine
subroutine f_real( me, x )
class(A_t) :: me
real :: x
print *, "f_real :", x
endsubroutine
subroutine g( me, str, arg ) ! 'arg' <-> 'input'
class(B_t) :: me
character(*) :: str
class(*) :: arg
print *, "g : ", str
select type ( arg )
type is ( integer )
call me % A % f( arg )
type is ( real )
call me % A % f( arg )
endselect
endsubroutine
end module
program main
use test_m
implicit none
type(A_t) :: A
type(B_t) :: B
call A % f( 100 )
call A % f( 1.23 )
call B % g( "hi", -100 )
call B % g( "yo", -1.23 )
end
结果与gfortran-4.8&amp; 7.1:
f_int : 100
f_real : 1.23000002
g : hi
f_int : -100
g : yo
f_real : -1.23000002
但上面的代码与在f_int
内调用特定函数(f_real
和select type
)一样冗长,因此它可能不是OP正在寻找的......
稍微不同的方法可能是将f
定义为接收class(*)
变量的特定函数,在select type
中使用f
,然后调用此{{1}来自f
。如果g
只是从arg
(或任何其他函数)传递到g
,这可能会使代码更简单。
f
上述方法也可用于扩展类型,例如
module test_m
implicit none
type A_t
contains
procedure :: f_int
procedure :: f_real
procedure :: f
endtype
type B_t
type(A_t) :: A
contains
procedure :: g
endtype
contains
contains
subroutine f_int( me, n )
class(A_t) :: me
integer :: n
print *, "f_int : ", n
endsubroutine
subroutine f_real( me, x )
class(A_t) :: me
real :: x
print *, "f_real :", x
endsubroutine
subroutine f( me, arg )
class(A_t) :: me
class(*) :: arg
select type ( arg )
type is ( integer ) ; call me % f_int ( arg )
type is ( real ) ; call me % f_real( arg )
endselect
endsubroutine
subroutine g( me, str, arg )
class(B_t) :: me
character(*) :: str
class(*) :: arg
print *, "g : ", str
call me % A % f( arg )
endsubroutine
end module
但我希望在不使用module test_m
implicit none
! same definition for A_t
type, extends(A_t) :: B_t
contains
procedure :: g
endtype
contains
! same definition for f_int, f_real, and f
subroutine g( me, str, arg )
class(B_t) :: me
character(*) :: str
class(*) :: arg
print *, "g : ", str
call me % A_t % f( arg )
endsubroutine
end module
的情况下直接将arg
传递给通用函数f
还有其他方法。