如何声明过程参数的接口部分,该参数又引用同一模块的用户派生类型?

时间:2011-12-18 02:27:44

标签: types interface module fortran

如以下代码示例所示,person_list是用户派生类型,包含类型绑定过程compare_persons。我希望compare_persons能够接受某个compareFunc组作为其参数之一,因此声明compareFunc的接口部分。请注意compareFunc的第一个参数是person_list类型。 (正如您所知,person_list与Delphi的VCL中的TStringList类似。)

编译无法继续。错误消息是:

[root@localhost new]# ifort -c lib1.f90 
lib1.f90(26): error #6457: This derived type name has not been declared.   [PERSON_LIST]
                    TYPE(person_list) :: persons    !   error #6457: This derived type name has not been declared.   [PERSON_LIST]
-------------------------^
lib1.f90(23): error #6404: This name does not have a type, and must have an explicit type.   [PERSONS]
                FUNCTION compareFunc(persons, index1, index2)    !   error #6404: This name does not have a type, and must have an explicit type.   [PERSONS] 
-------------------------------------^
compilation aborted for lib1.f90 (code 1)

错误消息似乎表明模块之间存在循环引用?因此,我想知道如何为过程参数声明接口部分,而过程参数又引用同一模块的用户派生类型?任何见解将不胜感激!

PS:尝试此模块的原因是OO编程风格的偏好。尝试fortran的原因是一个很大的代码库。

PS:编译器是英特尔Fortran编译器,版本如下:

[root@localhost new]# ifort --version
ifort (IFORT) 12.1.0 20111011
Copyright (C) 1985-2011 Intel Corporation.  All rights reserved.

代码示例为:

MODULE lib1

    TYPE person_list

    CONTAINS
        PROCEDURE, PASS :: compare_persons

    END TYPE

CONTAINS

    FUNCTION compare_persons(this, index1, index2, compareFunc)

        IMPLICIT NONE

        INTEGER :: compare_persons
        CLASS(person_list) :: this
        INTEGER, INTENT(IN) :: index1
        INTEGER, INTENT(IN) :: index2

        INTERFACE
            FUNCTION compareFunc(persons, index1, index2)    !   error #6404: This name does not have a type, and must have an explicit type.   [PERSONS] 
                IMPLICIT NONE
                INTEGER :: compareFunc
                TYPE(person_list) :: persons    !   error #6457: This derived type name has not been declared.   [PERSON_LIST]
                INTEGER :: index1
                INTEGER :: index2
            END FUNCTION compareFunc
        END INTERFACE

        compare_persons = compareFunc(this, index1, index2)

    END FUNCTION compare_persons

END MODULE lib1

tpg2114找出解决方案!

MODULE lib1

    TYPE person_list

    CONTAINS
        PROCEDURE, PASS :: compare_persons

    END TYPE

    INTERFACE
        FUNCTION CompareFuncInterface(persons, index1, index2)  
            IMPORT person_list
            IMPLICIT NONE
            INTEGER :: CompareFuncInterface
            TYPE(person_list), INTENT(IN) :: persons    
            INTEGER, INTENT(IN) :: index1
            INTEGER, INTENT(IN) :: index2
        END FUNCTION CompareFuncInterface
    END INTERFACE

CONTAINS

    FUNCTION compare_persons(this, index1, index2, compareFunc)

        IMPLICIT NONE

        INTEGER :: compare_persons
        CLASS(person_list), INTENT(IN) :: this
        INTEGER, INTENT(IN) :: index1
        INTEGER, INTENT(IN) :: index2
        PROCEDURE (CompareFuncInterface) :: compareFunc

        compare_persons = compareFunc(this, index1, index2)

    END FUNCTION compare_persons

END MODULE lib1

1 个答案:

答案 0 :(得分:5)

好的,我明白了:

MODULE lib1

   TYPE :: persons
   CONTAINS
      PROCEDURE, PASS :: compare_persons
   END TYPE persons

   INTERFACE
      INTEGER FUNCTION compareFunc_interface(personsIn, index1, index2)
         IMPORT persons
         IMPLICIT NONE
         TYPE(persons), INTENT(IN) :: personsIn
         INTEGER, INTENT(IN) :: index1
         INTEGER, INTENT(IN) :: index2 
      END FUNCTION compareFunc_interface
   END INTERFACE


CONTAINS 
   FUNCTION compare_persons(this, index1, index2, compareFunc)
      IMPLICIT NONE

      INTEGER :: compare_persons
      CLASS(persons) :: this
      INTEGER :: index1
      INTEGER :: index2
      PROCEDURE(compareFunc_interface) :: compareFunc
   END FUNCTION compare_persons
END MODULE lib1

从2003标准开始,IMPORT语句带来了从主机作用域单元到本地作用域单元的定义。如果您使用的是其他模块,INTERFACE需要USE语句。但是,由于您是从较高的范围单元格导入,因此使用IMPORT以及要添加到该范围内的事项列表

修改

另请注意,我在类型绑定过程的声明中添加了PASS。虽然不是必需的(因为这是默认操作),但我更喜欢始终放置PASSNOPASS,以便始终明确意图。这有助于程序员(确保他们做他们认为他们正在做的事情)和任何阅读代码的人。