2016-09-22 29 views
6

:gerçek argüman olarak bir işleve bir jenerik prosedürü geçme ben bir işleve gerçek argüman olarak bir jenerik prosedür geçmesi çalışılıyor

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 notlar bunu yapamaz:

Ben gene 2008 Standart bölümü üzerinden okuyorum

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) 

: ifort 17 ile Benzer

test.f90:43:16: 

write(*,*)func3(func,2.,3.) 
       1 
Error: GENERIC procedure ‘func’ is not allowed as an actual argument at (1) 
, ric arayüzleri ve böyle bir kısıtlama bulamıyorum. Derleyicinin, derleme zamanında genel arabirimi çözümleyememesinin nedenini de düşünemiyorum. Bağırmam bana bunun yapılabilmesi gerektiğini söylüyor ama doğru yaklaşıma sahip olmayabilirim. Bunu yapmak için standartlara uygun bir yol biliyor musunuz?

cevap

5

Hayır, buna izin verilmiyor. Aslında, jenerik INTRINSIC işlevlerini kukla argümanlar olarak bile aktaramazsınız.

standart uyumlu yolu doğrudan sağ belirli işlevleri kullanmaktır. INTRINSIC işlevleriyle, belirli bir standart adı olmadığında, doğru tür için bir sarıcı yazmanız gerekir. Örneğin

:

call integrate(derf,0.,1.) 

    contains 
    function derf(x) 
     real(dbl) :: derf 
     real(dbl), intent(in) :: x 
     derf = erf(x) 
    end function 
    end 

mevcut özel fonksiyon olmadığı için çift hassasiyetli gerçek (veya başka) erf() sürümünü geçirmek istiyorsanız gereklidir.

+1

daima açık ve öz, sayesinde elde edilir. – milancurcic

+6

Belirli işlevleri kullanmanın Fortran 2015'te standart olmayacağını açıklayacağım. Bu noktada bir prosedür argümanı olarak içsel bir işlevi iletmenin bir yolu olmayacak ve standartlara uymak için sarmalayıcı yöntemini kullanmak zorunda kalacak. (Ayrıca Fortran 95'ten beri intrinsics için yeni isimlerin eklenmediğini de not ediyorum.) –

1

Fortran standardı, bir kişinin argüman olarak genel prosedürleri geçmesine izin vermez. İçsel işlevleri/alt programları geçmek için kullanıcı tanımlı sarıcı prosedürlerine başvurulmalıdır.

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