2016-09-22 8 views
6

मैं एक समारोह के लिए एक वास्तविक तर्क के रूप में एक सामान्य प्रक्रिया पारित करने के लिए प्रयास कर रहा हूँ:वास्तविक तर्क के रूप में एक समारोह के लिए एक क्रियाशील प्रक्रिया पासिंग

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 स्टैंडर्ड अनुभाग के माध्यम से पढ़ रहा हूँ अमीर इंटरफेस और मुझे इस तरह के प्रतिबंध नहीं मिल रहे हैं। मैं एक कारण के बारे में भी नहीं सोच सकता कि क्यों संकलक संकलन समय पर सामान्य इंटरफ़ेस को हल करने में सक्षम नहीं होगा। मेरा आंत मुझे बता रहा है कि यह करने योग्य होना चाहिए, लेकिन मेरे पास सही दृष्टिकोण नहीं हो सकता है। क्या आप ऐसा करने के लिए मानक-अनुरूप तरीके से जानते हैं?

उत्तर

5

नहीं, इसकी अनुमति नहीं है। असल में, आप सामान्य इंट्रिनिक्स कार्यों को डमी तर्क के रूप में भी पारित नहीं कर सकते हैं।

एक मानक अनुपालन तरीका सीधे सही विशिष्ट कार्यों का उपयोग करना है। INTRINSIC फ़ंक्शंस के साथ आपको कभी-कभी सही प्रकार के लिए एक रैपर लिखना चाहिए, जब विशिष्ट के पास मानक नाम नहीं होता है।

उदाहरण के लिए:

call integrate(derf,0.,1.) 

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

यदि आप कोई विशेष समारोह उपलब्ध न होने के कारण डबल परिशुद्धता असली (या किसी अन्य) erf() के संस्करण पास करना चाहते हैं आवश्यक है।

+1

हमेशा स्पष्ट और बिंदु, धन्यवाद करने के लिए अर्जित करता है। – milancurcic

+6

मैं टिप्पणी करूंगा कि विशिष्ट कार्यों का उपयोग फोरट्रान 2015 में गैर-मानक बन जाएगा। उस बिंदु पर एक आंतरिक तर्क को प्रक्रिया तर्क के रूप में पारित करने का कोई तरीका नहीं होगा और मानक-अनुरूप रहने के लिए रैपर विधि का उपयोग करना होगा। (मुझे यह भी ध्यान है कि फोरट्रान 95 के बाद से इंट्रिनिक्स के लिए कोई नया विशिष्ट नाम नहीं जोड़ा गया है।) –

1

फोरट्रान मानक किसी को जेनेरिक प्रक्रियाओं को तर्क के रूप में पारित करने की अनुमति नहीं देता है। आंतरिक कार्यों/subroutines पास करने के लिए किसी को उपयोगकर्ता परिभाषित रैपर प्रक्रियाओं का सहारा लेना चाहिए।

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 
संबंधित मुद्दे