键入绑定过程作为参数 [英] Type bound procedure as arguments

查看:213
本文介绍了键入绑定过程作为参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  module mod1 $ 

b $ b隐含无

类型type1
real :: a
包含
过程,pass :: f
结束类型

包含

实函数f(y,e)
class(type1),intent(in):: y
实数,意图(in):: e
f = y%a + e
结束函数

结束模块

程序测试

使用mod1
类型( type1):: t

t%a = 3e0
write(*,*)s(t%f)

包含

实函数s(g)
实数,外部:: g
s = g(5e0)+ 2e0
结束函数

结束程序

gfortran产生这个错误:

  write(*,*)s(t%f)
1
错误:期望的参数列表在(1)

但是我可以做的是:

 程序测试

t%a = 3e0
写(*,*)s(k)

包含

实函数s(g)
实数,外部:: g
s = g(5e0)+ 2e0
结束函数

实函数k(e)
实数,意图(in):: e
k = 3e0 + e
结束函数

结束程序

我认为问题与传递类型绑定程序作为参数,但我目前没有看到那里的答案如何帮助我。



编辑:



一个更好的例子(希望)显示难度:

  module mod2 
隐式无
包含

实函数(g)
接口
实函数g(x)
实数,意图(in):: x
结束函数
结束接口

s = g(5e0)+ 2e0
结束函数
结束模块

模块mod1
使用mod2

类型1
real :: a
包含
程序,pass :: f
程序,pass :: h
结束类型

包含

实函数f(y,e )
class(type1),intent(in):: y
real,intent(in):: e
f = y%a + e
结束函数

实函数h(y)
class(type1),intent(inout):: y
h = s(y%f)
结束函数
结束模块

程序测试

使用mod1
类型(type1):: t

t%a = 3e0
write(*,*)t%h
end program

编辑II:
好了,包装仍然和指针一起工作:

  module mod2 
隐式无
包含

实函数s(g)
接口
实函数g(x)
实数,意图(in):: x
结束函数
结束界面

s = g(5e0)+ 2e0
结束函数
结束模块

模块mod1
使用mod2

type type1
real :: a
包含
过程,pass :: f
过程,pass :: h
结束类型

class(type1),pointer :: help_w

包含

实函数f(y,e)
class(type1),intent(in ):: y
real,intent(in):: e
f = y%a + e
结束函数

实函数h(y)
class(type1),intent(inout),target :: y
help_w => y
h = s(wrap)
结束函数

函数wrap(x)
real,intent(in):: x
wrap = help_w% f(x)
结束函数
结束模块

程序测试

使用mod1
类型(type1):: t

t%a = 3e0
写(*,*)t%h()
结束程序

这当然不是一个漂亮的解决方案,但至少可以工作。

解决方案

一个包装。这是最直接的版本。需要将内部函数作为虚拟参数传递(F2008),但是如果 t 可以在那里,您也可以在模块中声明包装器。



注意我将 s 中的过程参数声明更改为更现代的 - 接口块。

 程序测试
使用mod1
类型(type1):: t

t%a = 3e0
write(*,*)s(wrap)

包含

实函数s(g)
接口
实函数g(x)
real,intent(in):: x
结束函数
结束接口

s = g(5e0)+ 2e0
结束函数
$ b (b)














$ b $ $ b

你错误的原因在链接问题的答案中有很好的描述,你不能通过类型绑定程序你试过的方式。

I want to pass a type bound procedures (as an external function) to another function as follows:

module mod1
   implicit none

   type type1
      real :: a
      contains
      procedure,pass :: f
   end type

contains

   real function f(y,e)
      class(type1), intent(in) :: y
      real,intent(in) :: e
      f=y%a+e
   end function

end module

program test

   use mod1
   type(type1) :: t

   t%a=3e0
   write(*,*) s(t%f)

contains

   real function s(g)
      real,external :: g
      s=g(5e0)+2e0
   end function

end program

gfortran produces gives this error :

       write(*,*) s(t%f)
                       1
Error: Expected argument list at (1)

But what I can do is:

program test

   t%a=3e0
   write(*,*) s(k)

contains

   real function s(g)
      real,external :: g
      s=g(5e0)+2e0
   end function

   real function k(e)
      real,intent(in) :: e
      k=3e0+e
   end function

end program

I think the problem is related to Passing type bound procedures as arguments, but I don't see at the moment how the answers there can help me.

EDIT:

A better example which (hopefully) shows the difficulty:

module mod2
   implicit none
contains

   real function s(g)
       interface
        real function g(x)
          real, intent(in) :: x
        end function
      end interface

      s=g(5e0)+2e0
   end function
end module

module mod1
   use mod2

   type type1
      real :: a
      contains
      procedure,pass :: f
      procedure,pass :: h
   end type

contains

   real function f(y,e)
      class(type1), intent(in) :: y
      real,intent(in) :: e
      f=y%a+e
   end function

   real function h(y)
      class(type1), intent(inout) :: y
      h=s(y%f)
   end function
end module

program test

use mod1
   type(type1) :: t

   t%a=3e0
   write(*,*) t%h
end program

EDIT II: Ok, the wrappers still work in combination with a pointer:

module mod2
   implicit none
contains

   real function s(g)
       interface
        real function g(x)
          real, intent(in) :: x
        end function
      end interface

      s=g(5e0)+2e0
   end function
end module 

module mod1 
   use mod2

   type type1
      real :: a
      contains
      procedure,pass :: f
      procedure,pass :: h
   end type

   class(type1),pointer :: help_w

contains

   real function f(y,e)
      class(type1), intent(in) :: y
      real,intent(in) :: e
      f=y%a+e
   end function

   real function h(y)
      class(type1), intent(inout),target :: y
      help_w => y
      h=s(wrap) 
   end function

   function wrap(x)
      real,intent(in) :: x
      wrap=help_w%f(x)
   end function 
end module

program test

use mod1
   type(type1) :: t

   t%a=3e0
   write(*,*) t%h()
end program

This is certainly not a beautiful solution but at least it works.

解决方案

You can write a wrapper. This is the most straightforward version. Requires passing internal function as a dummy argument (F2008), but you could declare the wrapper in a module too, if the t can bee there.

Note I changed the declaration of the procedure argument in s to something more modern - the interface block.

program test
   use mod1
   type(type1) :: t

   t%a=3e0
   write(*,*) s(wrap)

contains

   real function s(g)
      interface
        real function g(x)
          real, intent(in) :: x
        end function
      end interface

      s=g(5e0)+2e0
   end function

   function wrap(x)
     real, intent(in) :: x
     wrap = t%f(x)
   end function

end program

The reason for your error is well described in the answers to the linked question, you cannot pass type bound procedures the way you tried.

这篇关于键入绑定过程作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆