Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Fortran > [General] Перегрузка операторов


Автор: MrKreazy 2.9.2010, 15:00
Добрый день. Помогите пожалуйста разобраться со следующим моментом.
В программе необходимо производить много вычислений с использованием векторов (а также типов, расширяюших тип вектора), для облегчения работы и улучшения "читабельности" текста программы перегружаю операторы, в том числе оператор умножения:
Код

type T_Vector
   real x(max_dimensions)                 ! без ограничения общности. тестировать проще с 1/2 измерением
end type T_Vector
! ...
interface operator(*)
   module procedure vectors_dot_product,vectors_vec_num_product
end interface

Соответственно 1 и 2 функции выполняют скалярное умножение и умножение на число
Код

real function vectors_dot_product(vec1,vec2)
  type(T_Vector), intent(in) :: vec1,vec2
  t_vector_vecs_dot_product = dot_product(vec1%x,vec2%x)
end function t_vector_vecs_dot_product
type(T_Vector) function vectors_vec_num_product(vec,num)
  type(T_Vector), intent(in) :: vec
  real, intent(in) :: num
  t_vector_vec_num_product%x = num * vec%x 
end function t_vector_vec_num_product

Далее пытаюсь применить перегруженные операторы в основной программе:
Код

vec1=T_Vector((/1,2,3/))
vec2=T_Vector((/6,7,8/))
scalar=vec1*vec2                      ! верно, получаем 44
vec3=vec2*2                             ! вызывает ошибку компиляции

ошибка
Код

~/fortran/test/SRC/main.f90(33): error #6549: An arithmetic or LOGICAL type is required in this context.   [VEC2]
write(*,*) vec2*2
-----------^
~/fortran/test/SRC/main.f90(33): error #6355: This binary operation is invalid for this data type.   [VEC2]
write(*,*) vec2*2
-----------^

Внимание, вопрос: что я делаю не так? smile 

Заранее спасибо за внимание.

Автор: kemiisto 2.9.2010, 15:04
Навскидку. Написано, что второй параметр
Код

real, intent(in) :: num

а пытаетесь умножить на integer
Код

vec3=vec2*2


Либо vec3=vec2*real(2), либо дописать умножение на целое число.

Автор: MrKreazy 2.9.2010, 15:12
Спасибо, как все просто оказалось... В чем только не искал ошибку, а про самое простое забыл smile

p.s. не пишите не языках с автоматическим преобразованием типаов smile 

Автор: Фантом 2.9.2010, 22:44
Только зачем все это? Скалярное умножение уже встроено в язык и называется dot_product, умножение вектора на число и так реализуется в виде той же "звездочки".

Автор: MrKreazy 3.9.2010, 11:48
1) для того чтобы сократить запись, потому что когда в выражении пара скалярных произведений, да еще помноженных на что-нибудь, да еще и с парой параметров код становится трудно читаемым с 1 взгляда. 
2) кроме того, хотелось бы, чтобы запись в итоге больше походила на математическое выражение: писать a*b вместо dot_product(a%x,b%x),
3) плюс еще существует производный тип(основан на том же векторе, но еще с дополнительными параметрами), который после сложения/умножения должен образовывать вектор

приведу еще пример
Код

real function abc(v)
type(t_vector) v
! ... некоторое математическое выражение
end function grid_fn

а теперь нужно вычислить abc(v1-v2)... а вычитать нельзя(без перегрузки), дополнительная переменная-не вариант,  можно конечно передавать массив, но для меня так удобнее, да и зачем тогда вообще нужны типы?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)