Fortran 中未调用派生类型的自定义构造函数

Derived-type custom constructor not being called in Fortran

我正在尝试通过重载类型名称来制作自定义数据类型构造函数。但是,在进行调用时,将调用默认构造函数。我不明白我做错了什么。

这是有问题的代码片段。

    module test

    type, public :: foo
        character(512)   ::  str
        logical          ::  flag1
        logical          ::  flag2
    end type

    ! overload foo data-type
    interface foo
        module procedure make_foo
    end interface

    contains

    ! custom constructor
    function make_foo(str, flag1) result(self)
        implicit none
        type(foo)  ::  self
        character(512), intent(in)      :: str
        logical, intent(in), optional   :: flag1

        self % str  = str       ! this needs to be passed

        self % flag1 = .false.  ! this needs to be optional, and is false by default
        if (present(flag1)) self % flag1 = flag1

        self % flag2 = .false.  ! this cannot be passed and is always false by default

    end function

end module

program tmp
    use test
    implicit none 
    type(foo) :: a

    a = foo("hello") ! error here
end program

我想要一个自定义构造函数,它需要传递 str,允许 flag1 的可选规范,并且总是单独处理 flag2。 使用其构造函数测试数据类型时,它使用默认构造函数并抱怨缺少组件。

No initializer for component 'flag1' given in the structure constructor at (1)

我正在使用 gfortran 10.2.0

赋值语句

a = foo("hello")
如果可能,

被视为对泛型 foo 的引用,否则被视为对类型 foo 的默认结构构造函数的引用。

在这种情况下,通用 foo 具有一个特定接口:make_foo。为了引用通用 foo 我们需要 foo("hello")make_foo.

一致

伪参数 str 被声明为 character(512) 因此我们不允许用实际参数引用它文字常量 "Hello":那个常量是(很多)too short.1

编译器回退到默认结构构造函数,然后(正确地)抱怨有没有默认初始化的组件没有被赋予值。

可以通过以下两种方式之一修复此引用:

  • 提供长度至少为 512 的实参
  • 使str更短,或更好,假设长度

解决关于假定长度的问题 str:即使它的长度为 5,它仍然可以用于赋值 self%str = str 因为它会在末尾用空格填充以使其成为长度可达 self%str.

的 512

这是否足以认定引用“不一致”是无关紧要的:在尝试这样做时没有 Fortran 程序,因此不能要求编译器尝试该引用。