Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

- Intel Community
- Software Development Tools (Compilers, Debuggers, Profilers & Analyzers)
- Intel® Fortran Compiler
- Need help about the overriding operator in extened type and report a strange issue

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page

Highlighted
##

Li_L_

New Contributor I

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-22-2017
01:42 AM

Need help about the overriding operator in extened type and report a strange issue

module vector_ implicit none private public:: vector integer,parameter:: rp=8,ip=4 !types !----------------------- type:: vector private real(rp),allocatable,dimension(:):: vc contains generic:: init => init_vector procedure,private:: init_vector generic:: operator(*) => vsMultiply,svMultiply procedure,pass(lhs),private:: vsMultiply procedure,pass(rhs),private:: svMultiply end type vector !----- contains !&& pure subroutine init_vector(this,v) class(vector),intent(out):: this class(vector),intent(in):: v allocate( this%vc( size(v%vc) ) ) this%vc = v%vc end subroutine init_vector elemental function svMultiply(lhs,rhs) result(vr) real(rp),intent(in):: lhs class(vector),intent(in):: rhs type(vector):: vr allocate( vr%vc( size(rhs%vc) ) ) vr%vc = lhs * rhs%vc end function svMultiply !-- elemental function vsMultiply(lhs,rhs) result(vr) class(vector),intent(in):: lhs real(rp),intent(in):: rhs type(vector):: vr call vr%init( rhs * lhs ) end function vsMultiply !-- end module vector_ module polynomial_ use vector_ implicit none private public:: polynomial integer,parameter:: rp=8,ip=4 !----------------------------------------- type,extends(vector):: polynomial contains !the below p1=> error #5286: Ambiguous generic interface OPERATOR(*): previously declared specific procedure VECTOR_::SVMULTIPLY is not distinguishable from this declaration. [SPMULTIPLY] generic:: operator(*) => spmultiply procedure,pass(rhs),private:: spMultiply !the below p2=>error #8280: An overriding binding and its corresponding overridden binding must both be either subroutines or functions with the same result type, kind, and shape. [SVMULTIPLY] !procedure,pass(rhs),private:: svMultiply => spMultiply end type polynomial !----------------------------------------- contains !-- elemental function spMultiply(lhs,rhs) result(p) real(rp),intent(in):: lhs class(polynomial),intent(in):: rhs type(polynomial):: p call p%init(rhs) end function spMultiply end module polynomial_ program test use vector_ use polynomial_ implicit none print*, 'ok' end program test

here I meet some problems.

I have two types: one is <vector>, and another one is <polynomial> which is the subclass of <vector>

I want to override the operator(*) of <vector> in <polynomial> which makes the result follow the type of input

Method1: I tried to add <spMultiply> into the generic binding procedure, it leads problem1

Method2: I tried to override the <svMultiply>, it leads problem2

So is there anyone can help me solve this overriding procedure and realize my thought. I ever tried to change the class of output in <svMultiply> to <class(vector),allocatable::>, but <elemental> attribution refuse the declaration of <allocatable> for function output.

!!!the real problem!!!

Actually another worse problem is that I successfully override the operator<*> by method1 in a big code. Then a type(polynomial) can produce a type(polynomial) when multiplying REAL. But I can’t reproduce this successful compilation in this simplified version.

the f90 attached is a version can override operator<*>. it can run directly.

i want to know whether method1 is an legal overriding procedure for operator?

i use the VS2013+intelfortran2017

8 Replies

Highlighted
##

Li_L_

New Contributor I

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-22-2017
03:41 AM

i find the reason which

i find the reason which leads to this strange compiling behavior

once the operator(*) of <vector> is not the first overriden generic operator, method1 can be passed through the compiler check

like:

generic:: operator(+)=> <someproc>

added in line 16

but this compiling will still fails if the other overriden operator added behind the operator(*)

for now, i still want an legal and robust way to override the operator which can produce the different type output

<class,allocatable> is not a preferred way because <elemental> attribution is quite convenient for coding

Highlighted
##

FortranFan

Valued Contributor III

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-22-2017
11:00 AM

Quote:Li L. wrote:

Li L. wrote:

.. for now, i still want an legal and robust way to override the operator which can produce the different type output ..

@Li L,

What are all your use cases with the extended operator(*) in the child derived type? Note for situations that are like or similar to this:

z = x * y

where z is the child type and either x or y is the child type while the other is a real scalar of kind rp, all you would need is to introduce a defined assignment in the child type which has a second dummy argument of the parent type.

Highlighted
##

Li_L_

New Contributor I

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-22-2017
11:36 AM

Quote:FortranFan wrote:

FortranFan wrote:for example p1 = r * p2 *p3 if i don't override operator of polynomial r*p2=vector, rather than polynomial vector*p3 is wrong and nonsense as you say, a split step seems work. but it definitely confusing me in the future when i check the code with the literature. a compact expression, totally the same as the paper can help me work better

Quote:Li L.wrote:.. for now, i still want an legal and robust way to override the operator which can produce the different type output ..

@Li L,

What are all your use cases with the extended operator(*) in the child derived type? Note for situations that are like or similar to this:

z = x * y

where z is the child type and either x or y is the child type while the other is a real scalar of kind rp, all you would need is to introduce a defined assignment in the child type which has a second dummy argument of the parent type.

Highlighted
##

FortranFan

Valued Contributor III

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-22-2017
12:51 PM

Quote:Li L. wrote:

Li L. wrote:

.. for example

p1 = r * p2 *p3

if i don't override operator of polynomial

r*p2=vector, rather than polynomial

vector*p3 is wrong and nonsense.. when i check the code with the literature. a compact expression, totally the same as the paper can help me work better

Why is it nonsense? Based on what you show, a polynomial is effectively the same as vector; in fact, one can ask why even extend vector to make it a polynomial!

Also, what literature are you referring to? Which paper, and what is the "compact expression"? Does it have a design pattern in some other language you're trying to mimic with Fortran?

Highlighted
##

FortranFan

Valued Contributor III

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-22-2017
12:59 PM

Quote:Li L. wrote:

Li L. wrote:

..

for example

p1 = r * p2 *p3

..

Keep in mind you don't need necessarily work with type-bound generic operators; in fact, case can be made that abstraction for multiplications, etc. be achieved via module procedures rather than TBPs - many will find them clearer to understand and easier to implement, as aspect in which you express an interest. Moreover there may be some performance benefit given the fact the code can then work with explicit derived types rather than the polymorphic instances.

Highlighted
##

Li_L_

New Contributor I

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-22-2017
06:54 PM

Quote:FortranFan wrote:

FortranFan wrote:module procedures is a good choice

Quote:Li L.wrote:

..

for example

p1 = r * p2 *p3

..

Keep in mind you don't need necessarily work with type-bound generic operators; in fact, case can be made that abstraction for multiplications, etc. be achieved via module procedures rather than TBPs - many will find them clearer to understand and easier to implement, as aspect in which you express an interest. Moreover there may be some performance benefit given the fact the code can then work with explicit derived types rather than the polymorphic instances.

explicit derived type increase the code lines. but if you are definitely sure about the benefit of performance, no matter how much, i will try

anymore, can you reproduce the strange compiling. that method1: i can override the second or later generic operator by adding function in generic binding, but compiling fails when doing that for the first generic operator.

is that a compiler debug? this generic binding add is permitted or not?

Highlighted
##

FortranFan

Valued Contributor III

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-23-2017
08:39 AM

Quote:Li L. wrote:

Li L. wrote:

.. p1 = r * p1 * p2 ..

Upon further thought, you don't really need to override the scalar * vector and the vector * scalar operator in the polynomial type. You should be able to work by simply extending the generic operator(*) with 2 more procedures, a) with your ppMultiply where lhs -> class(polynomial) and rhs -> type(polynomial) and b) with, say, a vpMultiply where lhs -> type(vector) and rhs -> class(polynomial).

But you can also try the module procedure option and do performance comparisons.

Highlighted
##

Li_L_

New Contributor I

- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content

02-23-2017
09:56 AM

Quote:FortranFan wrote:

FortranFan wrote:

Quote:Li L.wrote:

.. p1 = r * p1 * p2 ..

Upon further thought, you don't really need to override the scalar * vector and the vector * scalar operator in the polynomial type. You should be able to work by simply extending the generic operator(*) with 2 more procedures, a) with your ppMultiply where lhs -> class(polynomial) and rhs -> type(polynomial) and b) with, say, a vpMultiply where lhs -> type(vector) and rhs -> class(polynomial).

But you can also try the module procedure option and do performance comparisons.

permitting the vector*polynomial is a dangerous logic for the program, as i think.

like if you considering the superclass as <2 dimensional vector>, and subclass as <3 dimensional vector>, which is a very nature inheritance

and in superclass we define real*2dvector = 2dvector

due to the lack of an effective overriding method

we have to admit the existence of real*3dvector = 2dvector, and then for correcting this logic, define an operation of <2dvector .op. 3dvector>

in mathematics, this operator definition breaks the completeness of 3d space. in code, this expression losses <z>

<class(2dvector),allocatable> as the output may help, but <elemental> is also a fundamental attribution for operator procedure

after a long time for considering this questions, i think a module interface is a safer way to override the intrinsic operator.

type binding operator is not suitable for extended type

For more complete information about compiler optimizations, see our Optimization Notice.