2

I have a following class, where I need to store objects of type neuron_t and connection_t.

!> Class representing a general network
type :: net_t
    private

    character(:), allocatable                 :: net_type              !< Type of the net
    integer(kind=integer_4neuro)              :: num_of_neurons        !< Number of neurons in the net
    character(:), allocatable                 :: training_method       !< Used training method

    class(neuron_t), allocatable              :: neuron_arr(:)         !< Array containing all neurons
    integer(kind=integer_4neuro), allocatable :: input_neuron_arr(:)   !< Array of input neuron indices
    integer(kind=integer_4neuro), allocatable :: output_neuron_arr(:)  !< Array of output neuron indices
    class(connection_t), allocatable          :: connection_arr(:)     !< Array of all connections

contains
    !> Prints information about the network to the standard output.
    procedure :: print_info => print_info_impl

    !> Saves the network instance to the Fortran binary file
    procedure :: save_net_bin => save_net_bin_impl

end type net_t

interface net_t
    !> Constructor of net_t class
    !! Loads complete info about network from file
    !! @param[in] filepath Path to the file with network configuration
    !! @return Returns pointer to the new instance of the class net_t
    module procedure :: new_net_1
end interface net_t

I tried to initialize the array like this

    allocate(new_obj)

    ! Init object
    do i=1,5
        new_obj%neuron_arr(i) =  mock_neuron_t()
    end do

but I'm getting the following error:

         new_obj%neuron_arr(i) =  mock_neuron_t()
        1
Error: Nonallocatable variable must not be polymorphic in intrinsic assignment at (1) - check that there is a matching specific subroutine for '=' operator

Do you know, what am I doing wrong? mock_neuron_t extends type neuron_t, so it should be ok.

EDIT:

Both neuron_t and connection_t classes are abstract, so I'm getting following error now after adding allocate(new_obj%neuron_arr):

     allocate(new_obj%neuron_arr)
             1
Error: Allocating new_obj of ABSTRACT base type at (1) requires a type-spec or source-expr

         new_obj%neuron_arr(i) =  mock_neuron_t()
        1
Error: Nonallocatable variable must not be polymorphic in intrinsic assignment at (1) - check that there is a matching specific subroutine for '=' operator
1

1 Answer 1

3

You cannot just assign to a polymorphic variable in an intrinsic assignment (=). You can only do that for allocatable variables and an array element is not an allocatable variable eventhough it is a part of an allocatable array. Remember all array elements must have the same dynamic type.

So if you wanted to have different elements of neuron_arr(:) to have a different type, that is not allowed.

But you can allocate the array to some single type and use the select type typeguard.

allocate(new_obj)

allocate(new_obj%neuron_arr)  !this allocates it to the declared type neuron_t!

! Init object
select type(a => new_obj%aneuron_arr)
  type is(neuron_t)
    do i=1,5
      a(i) =  mock_neuron_t()
    end do
end select

But then, if you will always have one fixed type there, wouldn't type(neuron_t) just suffice?

Sign up to request clarification or add additional context in comments.

7 Comments

Thank you very much! To be honest, I thought, that class(neuron_t) will set its type firmly to neuron_t... And I can't use type(neuron_t), because neuron_t is an abstract class.
Then you must allocate the array in the allocate stetement to the correct type and use that type in the select type. But I fear your design is wrong. The array must be allocated to one common non-abstract type at once). alocate(the_type :: the_array(size))
I've tried that (see Edit 2 in my question), but I'm getting Segmentation fault... I have really no idea, what's wrong now...
Who knows, I think that should be a new question with a new minimal reproducible example.
I've found the mistake - mock_neuron_t constructor was returning pointer instead of an instance itself. Insert this info, please, into your answer, I think it deserves to be accepted.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.