Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 接受不同类型的Fortran函数_Oop_Fortran - Fatal编程技术网

Oop 接受不同类型的Fortran函数

Oop 接受不同类型的Fortran函数,oop,fortran,Oop,Fortran,我有三个转换函数,用于转换角度,代码如下所示 返回的函数与输入的类型相同。这意味着 输入角度必须是程序员希望输出的类型 将其转换为所需的输出类型,例如使用 al=转换(实数(30),“度到弧度”) 我希望程序员能够做al=convert(30,“deg_to_rad”)。 我的想法是使用传输的策略来定义 输出类型 Real :: al, mold al = convert(30,"deg_to_rad", mold) al = convert(30.0,"deg_to_rad", mol

我有三个转换函数,用于转换角度,代码如下所示

返回的函数与输入的类型相同。这意味着 输入角度必须是程序员希望输出的类型 将其转换为所需的输出类型,例如使用
al=转换(实数(30),“度到弧度”)

我希望程序员能够做
al=convert(30,“deg_to_rad”)
。 我的想法是使用
传输的策略来定义
输出类型

Real :: al, mold    
al = convert(30,"deg_to_rad", mold)
al = convert(30.0,"deg_to_rad", mold)

Double Precision :: al, mold    
al = convert(30,"deg_to_rad", mold)
al = convert(30.0,"deg_to_rad", mold)
这就是我的功能。有一些想法会很好 关于如何进行和实施一个好的计划

Interface convert
  Module Procedure convert
  Module Procedure convert_real
  Module Procedure convert_dble
  Module Procedure convert_real128
End Interface convert

Contains

Function convert_real   &
  (                &
    qa, label      &
  )                &
 Result (qb)

Real, Intent (in) :: qa
Character (len=*), Intent (in) :: label

Real :: qb

If (label .contains. "angle:") Then

 Block

   Real :: pi, deg_to_rad

   pi = 22.0 / 7.0
   deg_to_rad  = pi  / 180.0

   Select Case (Trim (label))

     Case ("angle: deg_to_rad")
       qb = deg_to_rad * qa

   End Select

 End Block

End If

End Function convert_real


Function convert_dble  &
  (                    &
    qa, label          &
  )                    &
 Result (qb)

Double Precision, Intent (in) :: qa
Character (len=*), Intent (in) :: label

Double Precision :: qb


If (label .contains. "angle:") Then

 Block

   Double Precision :: pi, deg_to_rad

   pi = Dble(22) / Dble(7)
   deg_to_rad  = pi / Dble(180)

   Select Case (Trim (label))

     Case ("angle: deg_to_rad")
       qb = deg_to_rad * qa

   End Select

 End Block

End If

End Function convert_dble


Function convert_real128  &
  (                       &
    qa, label             &
  )                       &
 Result (qb)

Real (Real128), Intent (in) :: qa
Character (len=*), Intent (in) :: label

Real (Real128) :: qb

If (label .contains. "angle:") Then

 Block

   Real (Real128) :: pi, deg_to_rad
   pi = Real(22,Real128) / Real(7,Real128)
   deg_to_rad  = pi / Real(180,Real128)

   Select Case (Trim (label))

     Case ("angle: deg_to_rad")
       qb = deg_to_rad * qa

   End Select

 End Block

End If

End Function convert_real128
当输入和输出是不同的时,我尝试使用一个子程序 类型。然而,我得到下面的错误

Subroutine convertor  & 
  (                   &
    qa, label, qb     &
  )

Class (*), Intent (in) :: qa
Character (len=*), Intent (in) :: label

Class (*), Intent (out) :: qb

Select Type (qb)

 Type Is (Real)
   qb = convert (Real(qa),label)

 Type Is (Double Precision)
   qb = convert (Dble(qa),label)

 Type Is (Real (Real128))
   qb = convert (Real(qa,Real128),label)

End Select

End Subroutine convertor
这里是错误

gfortran -o build/lib/foul.o -c -ffree-form -g -J./build/lib lib/foul.f
gfortran -o build/lib/meidum.o -c -ffree-form -g -J./build/lib lib/meidum.f
lib/meidum.f:890.26:

   qb = convert (Real(qa),label)
                      1
Error: 'a' argument of 'real' intrinsic at (1) must be a numeric type
lib/meidum.f:893.26:

   qb = convert (Dble(qa),label)
                      1
Error: 'a' argument of 'dble' intrinsic at (1) must be a numeric type
lib/meidum.f:896.26:

   qb = convert (Real(qa,Real128),label)
                      1
Error: 'a' argument of 'real' intrinsic at (1) must be a numeric type

如果我明白你想做什么,这看起来不必要的复杂。不要使用
transfer
作为模型,而是使用算术固有函数,如
sin
。Fortran(自Fortran 77以来)可以根据参数自动区分各种正弦函数(实函数、双精度函数、四精度函数)。编写每个函数,然后编写一个
接口
,将它们列为
模块过程
,以使其通用。例如:

编辑: 这取决于你想要什么:

result = convert (input)
对我来说,函数返回的类型由参数
输入的类型控制似乎是最自然的。这就是我描述的,也是示例中显示的。如果
结果的类型不同,Fortran将在赋值中转换。。。缺点是,如果选择了编译器选项,则会生成警告。因此,如果您希望
result
的类型控制由
convert
计算的类型,则必须修改此技术。不能使用函数,因为函数返回不区分此重载。改用一个子例程,它将有一个参数来区分:

call convert (input, result)

这将在接口/模块过程中正常工作。我不知道为什么我认为这行不通。与赋值语句/函数表示法相比,它在使用上可能没有那么优雅。

问题之一是我不能将Class(*)用于函数的结果类型。因此,代码不能使用mold。这就是我一直试图做的。我有一个不同的实数、双精度和实数函数(real128)。输入类型必须与输出类型相同,才能使这些函数工作。可能需要有其他函数可以接受整数但输出实数。我无法找到函数如何知道返回类型的方法,除非程序员输入变量。我同意@M.S.B。请遵循所指问题中显示的示例。与
sin等内部函数一样,函数返回的类型与传递的参数相同。如果要将结果强制转换为另一种类型(或类型),请明确执行此操作,就像使用
sin
等一样。至于使用
TRANSFER
,您建议如何将64位实数的前32位或后32位转换为32位实数?传输不是类型转换,它只允许程序员编写潜在危险的代码(错误地)解释内存中的位。区别在于我必须使用一个子程序。然而,罪是一种功能。它根据输入变量返回类型。我需要一个小例子。请注意,OP围绕
transfer
所做的类比是关于其接口的工作方式,而不是其行为。也就是说-transfer有一个MOLD参数,[在某些方面]该参数用于选择要调用的通用传输过程的特定形式,从而改变函数结果的类型。