Перегрузка операторов доступа "[ ], (), { }" в Fortran 90 или 2003

Могу ли я перегрузить операторы доступа к записи [], () или {} для производных типов данных в FORTRAN 2003? В следующем примере я хочу определить схему доступа для производного типа данных "custom".

type custom
   integer, dimension(:), allocatable :: a
end type custom

type(custom) :: t

! after some initialization 
! .....
! .....
! .....
!
t%a( (/ 1, 2, 5 /) ) ! return entries located in positions 1, 2, and 5
t{ (/ 1, 2, 5 /) }   ! ?????? I want to define what stuff it should return 

Как я могу это сделать?

Обновить:

Обратите внимание, что я не хочу использовать массив "t%a" напрямую и выполнять обычные операции над массивами. Вместо этого я хочу переопределить операцию массива для типа данных "custom", чтобы t{'first'} возвращал указатель на первую запись в t%a или t%a(1), чтобы я мог сказать

t['first']= 18 

или же

print *, t['first']. 

Также с дополнительной перегрузкой я хочу получить такую ​​функциональность, как t[1] = 18, работает как t['first'] = 18.

1 ответ

Решение

Это скорее зависит от того, что вы подразумеваете под "возвращением".

Сам по себе пример, предложенный

t%a([1,2,5])   ! Using syntax offered by Fortran 2003

ничего не возвращает: это подобъект Со ссылкой на этот подобъект мы можем делать разные вещи:

print *, t%a([1,2,5])
t%a([1,2,5]) = 27
t%a([1,2,5]) = sin(real(t%a([1,2,5])))

но до сих пор нет понятия "возвращение". Важно то, что, как мы увидим, это не выражения.

Подойдя к вопросу, могу t[], t(), t{} что-то значит, тогда ответ, просто, "нет".* Вы можете, например, сказать:

t[1,2,5] = 1

означать

t%a[1,2,5] = 1

но это не то, чтобы рассмотреть.

Можно было бы создать выражение как

print *, t%ref([1,2,5])

но мы совсем на неопределимой территории.

Однако, как вы сейчас упоминаете указатели, есть еще что сказать. Хотя предпочтительный синтаксис t[1] или же t["first"] недоступно, у нас все еще есть выбор процедур с привязкой к типу. Например, вызов функции t%ref("first") вполне может быть в состоянии вернуть указатель на первый элемент t%a, Например, t%ref(1) может быть как

module reference

  implicit none

  type custom
     integer, dimension(:), allocatable :: a
   contains
     procedure ref
  end type custom

contains

  function ref(t, idx)
    class(custom), target, intent(in) :: t
    integer, intent(in) :: idx
    integer, pointer :: ref

    ref => t%a(idx)
  end function ref

end module reference

  use reference
  implicit none

  type(custom), target :: t
  integer, pointer :: b

  t%a = [1, 2, 3, 4, 5]

  print *, t%a
  b => t%ref(1)  ! Fortran 2008 allows direct assignment
  b = 8          ! but compiler support is very limited.
  print *, t%a

end

При желании ref можно сделать общим, чтобы t%ref("first") (и т. д.) приемлемо.


* Я основываюсь на том факте, что здесь t это скаляр Однако, как отметил Владимир Ф в комментарии () а также [] потенциально имеют в виду подлые вещи. Первый относится к массивам, а второй - к совместным массивам. Синтаксис, следовательно, является проблемой, но этот ответ больше смотрит на механизм, чем на синтаксис.

Другие вопросы по тегам