【发布时间】:2019-08-05 15:41:03
【问题描述】:
编辑以提供更多详细信息:
1) 提供库的代码不能(轻松)更改,因此应假定 profile_v1_type 和 profile_v2_type 是不可变的。
我已经实施了@francescalus 建议,它适用于我的小测试用例,但我认为我对这个问题还不够清楚。原因是我只能修改我的代码而不是来自库的代码/类型。问题是两者都会在导入的 profile_type 中包含t,这与父类型冲突。
但是我将实现一些东西,复制我想要的派生类型的内容,然后使用指针和类型绑定过程指向我想要使用的 profile_type 版本的组件。它不像我想要的那样干净,但比我现在的要好得多。
我支持一个与另一个有 2 个版本的代码交互的代码 - 这两个版本在接口上非常相似,虽然输入和输出的属性相同,但它们显然是不同的派生类型(它们来自不同的库并且不同在其中包含的变量中略有不同。这些类型中的大多数变量名称都是相同的,但很重要)。
(显然)有必要在运行时同时支持这两者,否则我会在编译时对这一切进行预处理。
目前,我已经懒惰地将每个版本(以及它使用的所有派生类型的版本)的相同代码复制并粘贴到单独的子例程(*_v1.f90、*_v2.f90)中。
这很烦人,而且不太容易维护。
我想做的是使用某种不关心它指向什么的指针(或者更确切地说,从它所指向的地方获取它的类型信息,并且足够聪明,可以知道里面有什么) .
正如我上面所说,名称大多相同,例如(t,例如温度)
来自 v1 的库:
TYPE profile_v1_type
REAL :: t
! loads of other stuff
END TYPE profile_v1_type
从库的 v2 开始:
TYPE profile_v2_type
REAL :: t
! loads of other stuff, more than the first version
END TYPE profile_v2_type
在我的代码中:
TYPE profile_container_type
TYPE(profile_v1_type) :: profile_v1
TYPE(profile_v2_type) :: profile_v2
! other arrays that are common inputs to both
END TYPE
! It's actually USE'd then allocated and initialised elsewhere, but I hope you get the idea
!USE profile_container_mod, ONLY : profile_container
TYPE(profile_container_type), TARGET :: profile_container
TYPE(*) :: p
REAL :: t1
!Version determined by a namelist
IF (Version == 1) THEN
p => profile_container % profile_v1
ELSE IF (Version == 2) THEN
p => profile_container % profile_v2
ENDIF
t1 = p % t + 1
.
.
.
ifort 19 给出了这些(预期的)错误:
test.f90(24): error #8776: An assumed type object must be a DUMMY argument. [P]
TYPE(*), POINTER :: p
--------------------^
test.f90(24): error #8772: An assumed type object must not have the ALLOCATABLE, CODIMENSION, POINTER, INTENT(OUT) or VALUE attribute. [P]
TYPE(*), POINTER :: p
--------------------^
test.f90(39): error #6460: This is not a field name that is defined in the encompassing structure. [T]
t1 = p % t + 1
---------^
compilation aborted for test.f90 (code 1)
将 TYPE(*) 替换为 CLASS(*) 给出(仍然预期):
test2.f90(39): error #6460: This is not a field name that is defined in the encompassing structure. [T]
t1 = p % t + 1 ! or some clever function...
---------^
compilation aborted for test2.f90 (code 1)
这可以通过选择您要处理的类型来解决,但我的意思是我想对 v1 和 v2 代码做同样的事情(它永远不会同时发生)。而且我想做很多次,不是在这个例程中,而是在十几个例程中。
如果响应者能够提供一个简单的示例,我愿意使用 C 指针。我曾尝试(不是最近)使用 C 互操作性来解决这个问题,但显然没有成功!
【问题讨论】:
-
您熟悉类型扩展吗?一个明显的方法是使用两种类型的联合的基类型,然后使用该基类型作为声明类型的多态指针。您的代码中是否可以进行此类更改?
-
有额外限制的新问题可能值得提出:很多人拥有无法更改的库代码,而且许多人可能想做类似的事情。这些限制有很大的影响。
标签: fortran derived-types