gpt4 book ai didi

arrays - Fortran 03/08(gfortran 编译器)中使用无限多态类型进行数组操作

转载 作者:行者123 更新时间:2023-12-02 03:11:07 24 4
gpt4 key购买 nike

我想通过class(*)功能(无限多态性)实现有用的数组操作(添加元素、删除元素、可分配/指针/二叉树结构的不同实现)。我使用 gfortran 5.0 应该可以处理这样的功能。我需要它,以免为我使用的每种类型重复相同的代码。

这应该看起来像

function add_element(array,element)
class(*),intent(in)::array(:)
class(*),intent(in)::element
class(*)::add_element(size(array)+1)
add_element=[array,element]
end function

问题是,当我尝试将此函数与某些确定类型一起使用时,返回结果时出现错误。如果没有select type,我就无法将class(*) 分配给某个明确的类型变量,而且我当然不希望每次使用它时都有选择类型结构。在子例程中,我不应该知道我想要使用的任何类型,因为我将创建其中的许多类型。

我尝试了 move_alloc、源代码的一些变体,尝试使用带有 intent(out) 参数的子例程等。但它不起作用。我认为它应该在参数属性中定义,与大小相同(带有源关键字?),但在标准中没有找到此类结构的示例或定义。当然,我会更多地研究这个标准(我不是专业程序员,而是物理学家,试图使我的程序可测试、可检查并且更容易更改),并且现在将简单地重复此代码以等待更好的解决方案,但也许有人知道在哪里在标准或某本书中搜索它?我认为这不仅与数组有关,而且与 class(*) 的使用有关,因为我认为应该有不知道类型的方法......

不知道我是否应该添加此子例程的其他无效形式的示例或它对错误的说明 - 否则问题将失去焦点。它可以被编译,但在所有情况下,在调用中分配给明确的类型都不起作用。对于参数 intent(out)(inout) 它不能从虚拟参数转到实际参数。从源重新分配会生成一个具有类型的对象(以及在我的示例中分配的结果),但该类型是隐藏的...并且我无法在子例程中使用选择类型,因为我不知道该类型。

此外,我不知道可以检查“相同类型”或此上下文中的某些内容的构造...

最佳答案

这不是一个简单的问题您可以使用选择类型,但Fortran没有像type is(type_of(x))这样的东西。另一方面,有 SAME_TYPE_AS()EXTENDS
TYPE_OF()
内在函数,但不能将它们用作类型保护。

有必要确保arrayelement的动态类型相同。

我认为这是标准的缺陷。

但是,您的方法仍然存在错误。您应该使函数结果可分配,以便能够将其分配给正确的动态类型:

class(*),可分配::add_element(:)

您可能会想到以下内容:(未经测试!使用 gfortran-4.9 ifort14 编译)

分配(add_element(size(array)+1), Mold=array)

但是如何实际传输我不知道的值,我担心如果不诉诸一些肮脏的技巧,这可能是不可能的。

你甚至不能使用transfer,这就是我看到的真正的缺陷。尽管你可以用多态模来调用传输

transfer(element, add_element(1))

你无法将它分配给数组元素

add_element(1) = transfer(element, add_element(1))

我的观点是 Fortran 缺乏类型保护选项,只能确保两个变量具有相同的动态类型。

您可能会想到以下内容:(未经测试!使用 gfortran-4.9 ifort14 编译)

function add_element(array,element)
use iso_c_binding
implicit none
class(*),intent(in)::array(:)
class(*),intent(in)::element
class(*), allocatable ::add_element(:)
type(c_ptr) :: tmp

interface
function memcpy(dest, src, n) bind(c)
use iso_c_binding
integer(c_intptr_t),value :: dest, src
integer(c_size_t) :: n
type(c_ptr) :: memcpy
end function
end interface

allocate(add_element(size(array)+1), mold=array)

tmp = memcpy(loc(add_element(size(array)+1)), &
loc(array), &
size(array, kind=c_size_t) * storage_size(array, c_size_t)/8_c_size_t )
tmp = memcpy(loc(add_element(size(array)+1)), &
loc(array(1)), &
storage_size(element, c_size_t)/8_c_size_t )

end function

关于arrays - Fortran 03/08(gfortran 编译器)中使用无限多态类型进行数组操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27165854/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com