我试图将泛型过程作为函数的实际参数传递:
module mymod
implicit none
interface func
module procedure :: func1
module procedure :: func2
endinterface func
contains
real function func1(x)
real,intent(in) :: x
func1 = 2*x
endfunction func1
real function func2(x,y)
real,intent(in) :: x
real,intent(in) :: y
func2 = 2*x + 3*y
endfunction func2
real function func3(func,x,y)
interface
real function func(x,y)
real,intent(in) :: x
real,intent(in) :: y
endfunction func
endinterface
real,intent(in) :: x
real,intent(in) :: y
func3 = func(x,y)
endfunction func3
endmodule mymod
program myprogram
use mymod
implicit none
write(*,*)func3(func,2.,3.)
endprogram myprogram
gfortran 6.2.0注意到我不能这样做:
test.f90:43:16:
write(*,*)func3(func,2.,3.)
1
Error: GENERIC procedure ‘func’ is not allowed as an actual argument at (1)
同样,使用ifort 17:
test.f90(39): error #8164: A generic interface name shall not be used as an actual argument. [FUNC]
write(*,*)func3(func,2.,3.)
----------------^
test.f90(39): error #6637: When a dummy argument is a function, the corresponding actual argument must also be a function. [FUNC]
write(*,*)func3(func,2.,3.)
----------------^
compilation aborted for test.f90 (code 1)
我正在阅读关于通用接口的2008标准部分,我找不到这样的限制。我也想不出编译器无法在编译时解析通用接口的原因。我的直觉告诉我这应该是可行的,但我可能没有正确的方法。你知道一种符合标准的方法吗?
答案 0 :(得分:7)
不,这是不允许的。实际上,你甚至不能将通用的INTRINSIC函数作为伪参数传递。
符合标准的方法是直接使用正确的特定功能。使用INTRINSIC函数时,有时必须为正确的类型编写包装器,具体时没有标准名称。
例如:
var test_object = {'id': 1, 'name': 'Test'};
var initial = [];
initial.push(test_object);
console.log(initial.includes(test_object));
var later = JSON.stringify(initial);
later = JSON.parse(later);
console.log(later.includes(test_object));
如果你想传递 call integrate(derf,0.,1.)
contains
function derf(x)
real(dbl) :: derf
real(dbl), intent(in) :: x
derf = erf(x)
end function
end
的双精度真实(或任何其他)版本,那么是必要的,因为没有特定的功能。
答案 1 :(得分:2)
Fortran标准不允许将通用过程作为参数传递。为了传递内部函数/子例程,必须求助于用户定义的包装程序。
module mymod
! Explicit typing only
implicit none
! Declare procedure interface
interface
function my_func(x, y) result (return_value)
real, intent(in) :: x, y
real :: return_value
end function my_func
end interface
contains
function func1(x) result (return_value)
real,intent(in) :: x
real :: return_value
return_value = 2*x
end function func1
function func2(x, y) result (return_value)
real, intent(in) :: x, y
real :: return_value
return_value = 2*x + 3*y
end function func2
function func3(user_defined_func, x, y) result (return_value)
procedure(my_func) :: user_defined_func
real, intent(in) :: x, y
real :: return_value
return_value = user_defined_func(x,y)
end function func3
end module mymod
program main
use ISO_Fortran_env, only: &
stdout => OUTPUT_UNIT, &
compiler_version, &
compiler_options
use mymod
! Explicit typing only
implicit none
write (stdout, *) func3(func2, 2.0, 3.0)
write (stdout, *) func3(foo, 2.0, 3.0)
write (stdout, *) func3(my_atan2, 2.0, 3.0)
print '(/4a/)', &
' This file was compiled using ', compiler_version(), &
' using the options ', compiler_options()
contains
! A user defined function
function foo(x, y) result (return_value)
real, intent(in) :: x, y
real :: return_value
return_value = 42
end function foo
! A wrapper function to invoke the intrinsic atan2
function my_atan2(x, y) result (return_value)
real, intent(in) :: x, y
real :: return_value
return_value = atan2(x,y)
end function my_atan2
end program main
产量
gfortran -std=f2008ts -o main.exe mymod.f90 main.f90
./main.exe
13.0000000
42.0000000
0.588002622
This file was compiled using GCC version 6.1.1 20160802 using the options -mtune=generic -march=x86-64 -std=f2008ts