Перегрузка операторов доступа "[ ], (), { }" в 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
это скаляр Однако, как отметил Владимир Ф в комментарии ()
а также []
потенциально имеют в виду подлые вещи. Первый относится к массивам, а второй - к совместным массивам. Синтаксис, следовательно, является проблемой, но этот ответ больше смотрит на механизм, чем на синтаксис.