为什么覆盖参数的名称必须与抽象接口的名称相匹配?
Why do the names of overriding arguments have to match those of the abstract interface?
为什么覆盖过程中的参数名称需要与抽象接口的参数名称相匹配?
我明白这些参数的 TYPE
、INTENT
等显然需要匹配接口,但编译器为什么要关心我所说的变量?
在下文中,我定义了一个简单的抽象实用程序 class,其中包含一个采用双精度参数的延迟过程 EVAL
。
!------------------------------------- an abstract utility class !
type, abstract :: func_1d
contains
procedure(interface_1d),deferred :: eval
end type func_1d
!-------------------------------------------- interface for eval !
abstract interface
function interface_1d(this,data) result(rval)
import :: func_1d
class(func_1d), intent(inout) :: this
real*8 , intent(in) :: data
real*8 :: rval
end function interface_1d
end interface
定义覆盖 class 和 EVAL
的实现:
type, extends(func_1d) :: foo
contains
procedure, pass :: eval => eval_foo
end type foo
function eval_foo(this,another_variable_name) result(rval)
implicit none
class(foo), intent(inout) :: this
real*8, intent(in) :: another_variable_name
real*8 :: rval
!! etc
end function eval_foo
我从 gfortran
得到以下错误:
Error: Dummy argument 'another_variable_name' of 'eval' at (1) should be named 'data'
as to match the corresponding argument of the overridden procedure
如果我用 DATA
代替 ANOTHER_VARIABLE_NAME
,一切都会按预期编译和运行。
但这对我来说似乎很愚蠢。我希望能够多次从 FUNC_1D
继承,在各种情况下每次都被迫调用我的变量 DATA
似乎很荒谬。
我不明白为什么编译器应该对参数的 TYPE
和 INTENT
感兴趣?
详细阐述 High Performance Mark 的评论
I don't know but I suspect that it may be down to Fortran's argument keyword capabilities, which mean that you can call your function like this fun_1d(data=the_data,this=that)
, that is you can name the arguments in the call rather than rely on position matching.
考虑以下因素
type, extends(func_1d) :: foo
contains
procedure, pass :: eval => eval_foo
end type foo
type, extends(func_1d) :: bar
contains
procedure, pass :: eval => eval_bar
end type bar
使用带有接口的适当过程定义
real*8 function eval_foo(this,foo_var)
class(foo), intent(inout) :: this
real*8, intent(in) :: foo_var
end function
real*8 function eval_bar(this,bar_var)
class(bar), intent(inout) :: this
real*8, intent(in) :: bar_var
end function
然后
class(func_1d), allocatable :: baz
allocate (foo_or_bar :: baz) ! For one of the types foo, bar
哪个参数关键字有意义?
print*, baz%eval(data=s)
print*, baz%eval(foo_var=s)
print*, baz%eval(bar_var=s)
[在某些情况下,这会更加明显,尤其是使用可选的伪参数。]
该标准要求您保留相同的虚拟参数名称(很可能会避免上述问题)。参见 12.4.1 ISO/IEC 1539-1:2010:
12.4.1 Interface and abstract interface
The interface of a procedure determines the forms of reference through which it may be invoked. The procedure’s
interface consists of its name, binding label, generic identifiers, characteristics, and the names of its dummy
arguments. The characteristics and binding label of a procedure are fixed, but the remainder of the interface may
differ in differing contexts, except that for a separate module procedure body (12.6.2.5), the dummy argument
names and whether it is recursive shall be the same as in its corresponding separate interface body (12.4.3.2).
这表明使用同一接口的单独过程应具有与该接口相同的虚拟参数名称。 4.5.7.3进一步加强了这一点:
The overriding and overridden type-bound procedures shall satisfy the following conditions.
- [...]
- Dummy arguments that correspond by position shall have the same names and characteristics, except for the type of the passed-object dummy arguments.
为什么覆盖过程中的参数名称需要与抽象接口的参数名称相匹配?
我明白这些参数的 TYPE
、INTENT
等显然需要匹配接口,但编译器为什么要关心我所说的变量?
在下文中,我定义了一个简单的抽象实用程序 class,其中包含一个采用双精度参数的延迟过程 EVAL
。
!------------------------------------- an abstract utility class !
type, abstract :: func_1d
contains
procedure(interface_1d),deferred :: eval
end type func_1d
!-------------------------------------------- interface for eval !
abstract interface
function interface_1d(this,data) result(rval)
import :: func_1d
class(func_1d), intent(inout) :: this
real*8 , intent(in) :: data
real*8 :: rval
end function interface_1d
end interface
定义覆盖 class 和 EVAL
的实现:
type, extends(func_1d) :: foo
contains
procedure, pass :: eval => eval_foo
end type foo
function eval_foo(this,another_variable_name) result(rval)
implicit none
class(foo), intent(inout) :: this
real*8, intent(in) :: another_variable_name
real*8 :: rval
!! etc
end function eval_foo
我从 gfortran
得到以下错误:
Error: Dummy argument 'another_variable_name' of 'eval' at (1) should be named 'data' as to match the corresponding argument of the overridden procedure
如果我用 DATA
代替 ANOTHER_VARIABLE_NAME
,一切都会按预期编译和运行。
但这对我来说似乎很愚蠢。我希望能够多次从 FUNC_1D
继承,在各种情况下每次都被迫调用我的变量 DATA
似乎很荒谬。
我不明白为什么编译器应该对参数的 TYPE
和 INTENT
感兴趣?
详细阐述 High Performance Mark 的评论
I don't know but I suspect that it may be down to Fortran's argument keyword capabilities, which mean that you can call your function like this
fun_1d(data=the_data,this=that)
, that is you can name the arguments in the call rather than rely on position matching.
考虑以下因素
type, extends(func_1d) :: foo
contains
procedure, pass :: eval => eval_foo
end type foo
type, extends(func_1d) :: bar
contains
procedure, pass :: eval => eval_bar
end type bar
使用带有接口的适当过程定义
real*8 function eval_foo(this,foo_var)
class(foo), intent(inout) :: this
real*8, intent(in) :: foo_var
end function
real*8 function eval_bar(this,bar_var)
class(bar), intent(inout) :: this
real*8, intent(in) :: bar_var
end function
然后
class(func_1d), allocatable :: baz
allocate (foo_or_bar :: baz) ! For one of the types foo, bar
哪个参数关键字有意义?
print*, baz%eval(data=s)
print*, baz%eval(foo_var=s)
print*, baz%eval(bar_var=s)
[在某些情况下,这会更加明显,尤其是使用可选的伪参数。]
该标准要求您保留相同的虚拟参数名称(很可能会避免上述问题)。参见 12.4.1 ISO/IEC 1539-1:2010:
12.4.1 Interface and abstract interface
The interface of a procedure determines the forms of reference through which it may be invoked. The procedure’s interface consists of its name, binding label, generic identifiers, characteristics, and the names of its dummy arguments. The characteristics and binding label of a procedure are fixed, but the remainder of the interface may differ in differing contexts, except that for a separate module procedure body (12.6.2.5), the dummy argument names and whether it is recursive shall be the same as in its corresponding separate interface body (12.4.3.2).
这表明使用同一接口的单独过程应具有与该接口相同的虚拟参数名称。 4.5.7.3进一步加强了这一点:
The overriding and overridden type-bound procedures shall satisfy the following conditions.
- [...]
- Dummy arguments that correspond by position shall have the same names and characteristics, except for the type of the passed-object dummy arguments.