2017-07-12 13 views
2

この追加テキストの形状に関係なく、スカラーオブジェクトのコンポーネントにテキストを追加します。タイプバインドされた要素手続きのインテント(inout)として渡されたオブジェクト

これを試すには、要素入力引数を持ち、渡されたオブジェクトであるintent(inout)引数が1つのみの要素手続きを作成します。ここで

はMWEです:

module add_mod 
    implicit none 

    type obj_A 
    character(len=:), allocatable :: Message 
    contains 
    procedure, pass(objA) :: add 
    procedure, pass(objA) :: write 
    end type 

contains 
    elemental subroutine add(objA, text) 
     implicit none 

     class(obj_A), intent(inout)     :: objA 
     character(len=*), intent(in)     :: text 

     objA%Message=objA%Message//text 
    end subroutine add 

    impure elemental subroutine write(objA, text) 
     implicit none 

     class(obj_A), intent(in)     :: objA 
     character(len=*), intent(in)     :: text 

     print*,'write ', text 
    end subroutine write 
end module 


program test 
    use add_mod 
    implicit none 

    type(obj_A) :: testA 


    call testA%add('toto') 
    print *, testA%Message 

    ! call testA%add(['toto','abcc','d,ef']) 
    print *, testA%Message 

    call testA%write(['toto','abcc','d,ef']) 

end program 

私はラインcall testA%add(['toto','abcc','d,ef'])をコメントしてみましょう場合は、それが正常に動作します。私はコメントを外した場合でも、私は、それが渡されたオブジェクトのintent(in)によるものである

Error: Actual argument at (1) for INTENT(INOUT) dummy 'objA' of ELEMENTAL subroutine 'add' is a scalar, but another actual argument is an array`

が、私はそれがtestA%write呼び出しで正しい理由を理解コンパイル時にエラーが発生しています。この場合、コンパイラは、1つの引数がスカラー形状であり、もう1つが配列形状であることを理解しています。

testA%add(['toto','abcc','d,ef'])の場合、obj_Aintent(inout)という配列形式にする必要があることも理解しています。これは、入力用のテキストがスカラーであるためです。したがって、それを行う正しい方法ではありません。

このテキストの形に関係なく、obj_A%Messageにテキストを追加する正しい方法はありますか?

+0

このテキストの形を持たずにobj_Aに含まれるMessageにテキストを追加したいと思います。私が見た唯一の解決策は汎用プロシージャの使用ですが、私はその解決方法を避けたいと思います。 –

+0

スカラー引数とベクトル引数の両方を処理したい場合は、汎用プロシージャーを避ける方法はありません。 –

答えて

3

elementalサブルーチンを使用する場合は、配列入力と配列出力[要素ごとに操作が行われます]を指定できます。ただし、配列入力をスカラー出力(ここではtestA)に割り当てようとしています。

期待どおりのサイズ3、あなたの日常作品の配列の出力を使用した場合:

module add_mod 
    implicit none 

    type obj_A 
    character(len=:), allocatable :: Message 
    contains 
    procedure, pass(objA) :: add 
    end type 

contains 
    elemental subroutine add(objA, text) 
     implicit none 

     class(obj_A), intent(inout)     :: objA 
     character(len=*),intent(in)     :: text 

     objA%Message=objA%Message//text 
    end subroutine add 
end module 

program test 
    use add_mod 
    implicit none 

    type(obj_A) :: testA 
    type(obj_A) :: testB(3) 

    call testA%add('toto') 
    print *, testA%Message 

    call testB%add(['toto','abcc','d,ef']) 
    print *, testA%Message 
    print *, testB(1)%Message, testB(2)%Message, testB(3)%Message 
end program 

をここでスカラー出力する文字列の配列を追加するためのバージョンです。このコンステレーションのために、サブルーチンはelementalにはなりません。しかし、それはpureことができます:

module add_mod 
    implicit none 

    type obj_A 
    character(len=:), allocatable :: Message 
    contains 
    procedure, pass(objA) :: add 
    end type 

contains 
    pure subroutine add(objA, text) 
     implicit none 

     class(obj_A), intent(inout)     :: objA 
     character(len=*), dimension(:), intent(in) :: text 
     integer :: i 

     do i=1,size(text) 
     objA%Message=objA%Message//text(i) 
     enddo !i 
    end subroutine add 
end module 

program test 
    use add_mod 
    implicit none 

    type(obj_A) :: testA 

    call testA%add(['toto']) 
    print *, testA%Message 

    call testA%add(['toto','abcc','d,ef']) 
    print *, testA%Message 
end program 

最後に、スカラと配列の両方の引数をサポートするために、あなたが提供して結合し、いくつかの実装をしてから、同じ名前でそれらを提供するためにgenericインタフェースを使用する必要があります。

module add_mod 
    implicit none 

    type obj_A 
    character(len=:), allocatable :: Message 
    contains 
    generic :: add => add1, add2 
    procedure, pass(objA) :: add1 
    procedure, pass(objA) :: add2 
    end type 

contains 
    pure subroutine add1(objA, text) 
     implicit none 

     class(obj_A), intent(inout)     :: objA 
     character(len=*), dimension(:), intent(in) :: text 
     integer :: i 

     do i=1,size(text) 
     objA%Message=objA%Message//text(i) 
     enddo 
    end subroutine add1 

    pure subroutine add2(objA, text) 
     implicit none 

     class(obj_A), intent(inout)     :: objA 
     character(len=*), intent(in)     :: text 

     objA%Message=objA%Message//text 
    end subroutine add2 
end module 

program test 
    use add_mod 
    implicit none 

    type(obj_A) :: testA 

    call testA%add('toto') 
    print *, testA%Message 

    call testA%add(['toto','abcc','d,ef']) 
    print *, testA%Message 
end program 
関連する問題