类型绑定过程给出有关非多态传递对象伪参数的错误

Tor*_*Tor 4 fortran derived-types

我正在尝试编译以下Fortran模块(使用gfortran 7.2.0)。关键是要定义一个派生类型,该派生类型又包含bspline_3d来自bspline-fortran库(https://github.com/jacobwilliams/bspline-fortran)的两个派生类型实例。然后,我想定义一个类型绑定过程,该过程将依次调用这两种类型的类型绑定evaluate过程,并将结果返回为包含两个元素的数组。

当我尝试编译下面的模块时,出现一条错误消息,提示

     procedure  :: evaluate => evaluate_2d
             1
Error: Non-polymorphic passed-object dummy argument of 'evaluate_2d' at (1)
Run Code Online (Sandbox Code Playgroud)

我完全不了解错误消息。

我设法编译了以下简单的示例程序:http : //fortranwiki.org/fortran/show/Object-oriented+programming,据我所知,唯一的区别是在我的情况下,“ passed-object” “(this)本身确实具有派生类型成员变量(type(bspline_3d) :: fvx, fvy),而后者又可能包含各种内容。

module interpolator_module

use bspline_module
use parameters, only: WP

implicit none

private
public :: interpolator

type :: interpolator
    type(bspline_3d) :: fvx, fvy
    contains
        private
        procedure  :: evaluate => evaluate_2d
end type interpolator

contains
    function evaluate_2d(this, X, t) result(V)
        implicit none
        ! inputs
        type(interpolator),     intent(inout) :: this
        real(WP), dimension(2), intent(in)    :: X
        real(WP),               intent(in)    :: t
        ! output
        real(WP), dimension(2)                :: V
        ! local variables
        integer                               :: iflag
        integer, parameter                    :: d = 0

        call this%fvx%evaluate(X(1), X(2), t, d, d, d, V(1), iflag)
        call this%fvy%evaluate(X(1), X(2), t, d, d, d, V(2), iflag)
    end function
end module interpolator_module
Run Code Online (Sandbox Code Playgroud)

Vla*_*r F 6

传递的虚拟参数this必须始终是多态的。这意味着它必须是

 class(interpolator),     intent(inout) :: this
Run Code Online (Sandbox Code Playgroud)

并不是

 type(interpolator),     intent(inout) :: this
Run Code Online (Sandbox Code Playgroud)

这是类型绑定过程的基本要求。否则你不能使用扩展类型(子)的过程。


fra*_*lus 5

对于像这样定义的类型绑定过程

type my_type
 contains
  procedure :: proc
end type
Run Code Online (Sandbox Code Playgroud)

类型绑定过程具有传递的参数。也就是说,当

type(my_type) my_obj
call my_obj%proc
Run Code Online (Sandbox Code Playgroud)

使用时,对象my_obj在参数列表中。随着proc定义为

subroutine proc(me)
  type(my_type) me   ! Not correct
end subroutine
Run Code Online (Sandbox Code Playgroud)

然后call my_obj%proc就像call proc%(my_obj)1 那是错误消息的“传递对象伪参数”部分。

proc上面的定义中,传递对象的虚拟参数type(my_type) me是非多态的。您可以在其他地方阅读有关多态的信息,但要回答这个问题:传递对象的虚拟参数可能不是非多态的。它必须是多态的,使用声明class(my_type) me

subroutine proc(me)
  class(my_type) me   ! Polymorphic, declared type my_type
end subroutine
Run Code Online (Sandbox Code Playgroud)

这意味着可以传递my_type一个类型或扩展类型的对象my_type。这是Fortran语言的要求。

简而言之:更改您的

type(interpolator),     intent(inout) :: this
Run Code Online (Sandbox Code Playgroud)

class(interpolator),     intent(inout) :: this
Run Code Online (Sandbox Code Playgroud)

使事情变得复杂的是,例如,较早版本的gfortran在理解多态之前先了解类型绑定过程。这意味着周围有一些错误使用非多态传递对象的示例。


1我故意将绑定名称保留proc为该过程的名称。在这个问题的背景下会是call my_obj%evaluate(...)这样call evaluate_2d(my_obj, ...)