lookbook 发表于 2018-11-8 13:23:13

参数化类型如何绑定

本帖最后由 lookbook 于 2018-11-8 13:23 编辑

各位大佬好,代码如下:

      module m_a
         implicit none

         type :: bar(p, q)
            integer, kind :: p=4
            integer, len:: q=10
            real(kind=p),dimension(q) :: x
         contains
            procedure,pass(this) :: barsub
         end type bar

      contains
         subroutine barsub(this)
            class(bar), intent(in) :: this
            write (*,*) this%x
         end subroutine barsub
      end module


gfortran编译错误如下:
       procedure,pass :: barsub
               1
Error: Argument ‘this’ of ‘barsub’ with PASS(this) at (1) must be of the derived-type ‘bar’

小白还望大佬们赐教,谢谢!



liudy02 发表于 2018-11-8 14:43:41

参数化派生类型是个坑,
目前还不知道有哪个编译器能很好的支持所有参数化派生类型的标准,
我反正是放弃找别的路子
我也坐等大佬看有什么办法没有……

lookbook 发表于 2018-11-8 16:38:35

liudy02 发表于 2018-11-8 14:43
参数化派生类型是个坑,
目前还不知道有哪个编译器能很好的支持所有参数化派生类型的标准,
我反正是放弃找 ...

感觉你就是大佬呀。。。

liudy02 发表于 2018-11-8 16:42:22

lookbook 发表于 2018-11-8 16:38
感觉你就是大佬呀。。。

你看我的级别积分什么的就知道不是啊……
和你一样的萌新菜鸟……

楚香饭 发表于 2018-11-9 00:55:34

kind的参数必须要编译时确定,不能假定
len的参数可以假定。
所以,多个kind,就要写多个函数。

module m_a
implicit none
type :: bar(p, q)
    integer, kind :: p=4
    integer, len:: q=10
    real(kind=p),dimension(q) :: x
contains
    procedure:: barsub => barsub4 , barsub8
end type bar

contains

subroutine barsub4(this)
    type(bar(p=4,q=*)), intent(in) :: this
    write (*,*) this%q , this%p
end subroutine barsub4

subroutine barsub8(this)
    type(bar(p=8,q=*)), intent(in) :: this
    write (*,*) this%q , this%p
end subroutine barsub8

end module

Program Main
use m_a
type(bar(4,30)) :: x4_30
type(bar(4,20)) :: x4_20
type(bar(8,30)) :: x8_30
type(bar(8,20)) :: x8_20
call x4_30%barsub()
call x4_20%barsub()
call x8_30%barsub()
call x8_20%barsub()
End Program Main

liudy02 发表于 2018-11-9 10:17:10

本帖最后由 liudy02 于 2018-11-9 10:18 编辑

楚香饭 发表于 2018-11-9 00:55
kind的参数必须要编译时确定,不能假定
len的参数可以假定。
所以,多个kind,就要写多个函数。

因为IVF和gfortran都没有支持对参数化派生类型中(Len=:)对象的Allocate语句
所以原来我已经觉得参数化派生类型废掉了,
版主却向我展示了它的另外一种用法,确实可以用一种类型涵盖事实上的多种数据
不过这里我有一点点疑惑:
不同的Kind在这里的处理方式实际上还是用的不同的函数
并没有让程序写起来变得更为简洁
从减小单个文件或单个Module的角度,怎么感觉还是写成不同的TYPE封装进不同的Module文件更合适呢
这种参数化派生类型的优势或者是巧妙应用是什么呢……

楚香饭 发表于 2018-11-9 11:16:55

不同的kind,需要用不同的函数。这是肯定的,毕竟二进制代码(指令)完全不同。
如果你有很高的通用编程需求,可以考虑用C++,模板会让通用编程更方便。
(事实上,模板也是产生了多个目标代码的函数的)

Fortran在OOP方面还刚刚起步,尚需时间和契机来成熟。
这主要还是取决于需求,至少,我还没有太多这方面的需求。

至于哪个合适,就要自己斟酌了。写成不同type,可能在维护性上会有欠缺。
PS:我在实际应用中,参数化type也很少使用。

liudy02 发表于 2018-11-9 12:38:26

本帖最后由 liudy02 于 2018-11-9 12:40 编辑

楚香饭 发表于 2018-11-9 11:16
不同的kind,需要用不同的函数。这是肯定的,毕竟二进制代码(指令)完全不同。
如果你有很高的通用编程需 ...
原来如此,版主的解释让我终于明了Kind参数和Len参数为什么在编程上有不同之处了
写成不同的Type寻找上应该是要困难点,所以同一类型不同kind就要分别去找文件
另外如果对与这几种Kind的相关过程有一致性要求,确实也容易顾此失彼,不过反正自己一个人维护的话还好:-L
但是写在不同文件里边,从编辑灵活性上还是好些啊
非常感谢版主的理论解释和经验分享,对我相当具有启发性

lookbook 发表于 2018-11-9 15:58:36

liudy02 发表于 2018-11-9 12:38
原来如此,版主的解释让我终于明了Kind参数和Len参数为什么在编程上有不同之处了
写成不同的Type寻找上应 ...

其实有一个方法,只需要多一个module就行。就是在最底层定义一个kind常量,然后每个module都包含使用它即可。

module style
integer,parameter :: nnn=8
end module

module another

type anything
real(kind=nnn) :: a,b
balabala.....
.......
这样的话,关于绑定的函数也只要写一遍就行,但记得更改nnn之后要clean一下,然后再make。
我是这样处理的。

lookbook 发表于 2018-11-9 16:00:03

楚香饭 发表于 2018-11-9 00:55
kind的参数必须要编译时确定,不能假定
len的参数可以假定。
所以,多个kind,就要写多个函数。


大佬就是大佬,学习了,我去试试。
页: [1] 2 3
查看完整版本: 参数化类型如何绑定