在 Fortran 中重载等于运算符

2023-12-28

有没有办法超载=运算符,以便您可以编写如下例所示的赋值:

  module constants_mod
    integer,parameter :: dpn = selected_real_kind(14)
  end module

  module vectorField_mod
    use constants_mod
    implicit none
    private

    public :: vectorField
    public :: allocateX,allocateY,allocateZ
    public :: delete
    ! public :: operator(=)

    type vectorField
      integer,dimension(3) :: sx,sy,sz
      real(dpn),dimension(:,:,:),allocatable :: x,y,z
    end type

  interface delete
    module procedure deallocateVectorField
  end interface

  ! interface operator (=)
  !   module procedure vectorAssign
  ! end interface

  contains

    ! function vectorAssign(f) result(q)
    !   implicit none
    !   real(dpn),intent(in) :: f
    !   type(vectorField) :: q
    !   q%x = f; q%y = f; q%z = f
    ! end function

    ! subroutine vectorAssign(f,g)
    !   implicit none
    !   type(vectorField),intent(inout) :: f
    !   real(dpn),intent(in) :: g
    !   f%x = g; f%y = g; f%z = g
    ! end subroutine

    subroutine allocateX(field,Nx,Ny,Nz)
      implicit none
      type(vectorField),intent(inout) :: field
      integer,intent(in) :: Nx,Ny,Nz
      if (allocated(field%x)) deallocate(field%x)
      allocate(field%x(Nx,Ny,Nz))
      field%sx = shape(field%x)
    end subroutine

    subroutine allocateY(field,Nx,Ny,Nz)
      implicit none
      type(vectorField),intent(inout) :: field
      integer,intent(in) :: Nx,Ny,Nz
      if (allocated(field%y)) deallocate(field%y)
      allocate(field%y(Nx,Ny,Nz))
      field%sy = shape(field%y)
    end subroutine

    subroutine allocateZ(field,Nx,Ny,Nz)
      implicit none
      type(vectorField),intent(inout) :: field
      integer,intent(in) :: Nx,Ny,Nz
      if (allocated(field%z)) deallocate(field%z)
      allocate(field%z(Nx,Ny,Nz))
      field%sz = shape(field%z)
    end subroutine

    subroutine deallocateVectorField(field)
      implicit none
      type(vectorField),intent(inout) :: field
      deallocate(field%x,field%y,field%z)
      field%sx = 0; field%sy = 0; field%sz = 0
    end subroutine

  end module

  program test
  use constants_mod
  use vectorField_mod
  implicit none
  type(vectorField) :: a
  integer :: N = 1
  real(dpn) :: dt = 0.1
  call allocateX(a,N,N,N)
  call allocateY(a,N,N,N)
  call allocateZ(a,N,N,N)

  a%x = dble(1.0) ! want to avoid this
  a%y = dble(1.0) ! want to avoid this
  a%z = dble(1.0) ! want to avoid this

  a = real(1.0,dpn) ! want this instead (does not compile)

  call delete(a)

  end program

我尝试了两种不同的方法(如注释中所示),但收到错误消息,指出通用规范中存在语法错误(用于公开=操作员)。


=不是运算符,而是 Fortran 中的赋值,它们是非常不同的野兽。

对于 Fortran 90 中发现的经典可能性并在其他答案中得到了很好的解释,Fortran 2003 添加了更好的可能性,将重载运算符和赋值与派生类型绑定。

这样,您就可以确保在没有赋值的情况下不会导入类型(在这种情况下请注意 public 和 private 声明!)。它可能会产生非常不愉快的后果并且很难调试:

type vectorField
  integer,dimension(3) :: sx,sy,sz
  real(dpn),dimension(:,:,:),allocatable :: x,y,z
contains
  procedure :: assignVector
  generic :: assignment(=) => assignVector
end type

这样您就不必那么小心,以免忘记public :: assignment (=)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Fortran 中重载等于运算符 的相关文章

  • 使用 MacLaurin 展开的 Fortran Sine 函数的微小差异

    我正在用 Fortran 创建一个程序 它接受以弧度表示的 sin x 的 x 然后是要计算的项数 这是我的程序 Sine value using MacLaurin series program SineApprox implicit n
  • 识别操作系统

    我在 Intel 编译器上的 Fortran 90 代码取决于它运行的操作系统 例如 if OS win7 then do X else if OS linux then do y end if 我如何以编程方式执行此操作 您可以使用预处理
  • 如何使用“instanceof”实现泛型的“equals”方法?

    我有一堂课接受泛型 我想覆盖equals以一种不尴尬的方式 即看起来干净并且代码量最少的东西 但对于非常一般的用例 现在我有这样的事情 public class SingularNode
  • PHP 中的抽象类是什么?

    PHP 中的抽象类是什么 如何使用 抽象类是至少包含一个抽象方法的类 该方法中没有任何实际代码 只有名称和参数 并且已被标记为 抽象 这样做的目的是提供一种模板来继承并强制继承类实现抽象方法 因此 抽象类是介于常规类和纯接口之间的东西 此外
  • forrt1:严重(170):程序异常 - 堆栈溢出

    并提前感谢您的帮助 我已经编译了一个程序 不是我编写的 它在 Mac 上运行得很好 但是当我尝试在 Windows 上执行该程序时 在程序开始执行后不久 我收到以下错误消息 forrt1 严重 170 程序异常 堆栈溢出 我不是 ifort
  • 确定列表编号是否连续

    我在 Java 工作 我有一个无序列表 包含 5 个数字 范围从 0 100 没有重复 我想检测其中 3 个数字是否连续且没有间隙 例子 9 12 13 11 10 true 17 1 2 3 5 true 19 22 23 27 55 f
  • 为什么Python 3中实例方法可以作为类方法调用?

    考虑下面的类 class Foo object def bar self print self 在Python 2中 2 7 13 调用bar 作为类方法引发异常 gt gt gt Foo bar hello Traceback most
  • Fortran的性能

    Fortran 的表现计算机语言基准游戏 http shootout alioth debian org 出奇的糟糕 今天的结果显示 Fortran 在两项四核测试中分别排名第 14 和第 11 在单核测试中排名第 7 和第 10 现在 我
  • 如何创建一个每次调用公共方法时都会调用的方法?

    如何创建一个每次调用公共方法时都会调用的方法 您也可以说这是一个后方法调用挂钩 我当前的代码
  • 拦截对对象属性的 __getitem__ 调用

    问题 我怎样才能拦截 getitem 调用对象属性 解释 所以 场景如下 我有一个对象将类似字典的对象存储为属性 每次 getitem 该属性的方法被调用 我想拦截该调用并根据键对获取的项目进行一些特殊处理 我想要的看起来像这样 class
  • C++ 模板友元运算符重载

    我的代码有什么问题吗 template
  • 类模板上的运算符重载

    我在为模板类定义一些运算符重载时遇到一些问题 让我们以这个假设的类为例 template
  • 使用 OOP 结构进行复数加法和减法

    我这里有一个代码应该打印两个复数的和与差 给出的说明是 制定方法add subtract and print to be void and 使用构造函数的对象进行测试 public class Complex param args publ
  • 阶级等级制度中频繁的贬低总是邪恶的吗?

    据我所知 如果在类层次结构中频繁使用向下转型是没有好处的 我同意这一点 但是这条规则有哪些例外情况 如果有的话 这就是我的图形编辑器设计的薄弱之处 我有两个层次结构 其中几何图形层次结构与图形基元分离 像这样 public class Ge
  • 对对象数组进行排序

    我在使用 PHP 手册中的示例时遇到了问题 所以我想在这里问这个 我有一个对象数组 有没有办法根据对象的内容对其进行排序 例如我的数组是 Array 0 gt stdClass Object id gt 123 alias gt mike
  • 如何正确使用状态模式?

    在我的编程经验中 我遇到过一些状态模式的实现 并且完成了一些 我见过它们在各种场景中使用 主要是 UI 和解析 问题在于 所有这些在快速开发的压力下都变成了难以维护和理解的代码块 我正在考虑重构其中之一 但我无法在网上找到合适的资源 网上有
  • self.__dict__.update(**kwargs) 的风格是好是坏?

    在 Python 中 假设我有一些类 Circle 它继承自 Shape Shape 需要 x 和 y 坐标 此外 Circle 需要半径 我希望能够通过执行类似的操作来初始化 Circle c Circle x 1 y 5 r 3 Cir
  • 在 javascript 原型事件处理程序中保留“this”引用[重复]

    这个问题在这里已经有答案了 正确的保存方法是什么this存储在对象原型内的事件处理程序中的 javascript 引用 我不想创建像 this 或 that 这样的临时变量 而且我不能使用像 jQuery 这样的框架 我看到很多人谈论使用
  • 有没有办法在javascript中代理(拦截)一个类的所有方法?

    我希望能够在类本身的构造函数内代理类的所有方法 class Boy constructor proxy logic do something before each call of all methods inside class like
  • 带有过程参数的通用类型绑定过程

    我正在尝试编写一个通用的类型绑定过程 它将不同的回调函数作为参数 当编译以下代码 使用 ifort 12 1 3 时 我收到以下警告 module test type a type contains procedure t s gt at

随机推荐