I try to better understand the difference between const
from C/C++ and intent(in)
in Fortran in the context of classes.
C++:
If I const
the implicit this
argument to a member function and I return references to members of this
, these references have to be const T*
.
So the const
does not only apply to the scope of the function call, but also extends to all references "created" in that function call.
Fortran: If I intent(in)
the this
argument of a member function the intent(in)
only applies to the scope of the member function. I cannot mutate this
inside the member function, but I can return a reference and modify this
outside.
If I have the following more or less equivalent code for a Counter class in Fortran and C++ to test this and it seems to be correct.
#include <iostream>
class Counter {
int val{};
public:
auto next()
{
return val++;
};
const auto raw() const
{
const auto ptr = &val;
return ptr;
};
};
int main()
{
Counter c{};
std::cout << c.next() << "\n";
std::cout << c.next() << "\n";
auto ptr = c.raw();
// does not compile, as it is expected
*ptr = 0;
std::cout << c.next() << "\n";
return 0;
}
module counter_mod
implicit none(type, external)
private
public :: Counter_t
type :: Counter_t
private
integer :: val = 0
contains
procedure :: next
procedure :: raw
end type
contains
integer function next(this)
class(Counter_t), intent(inout) :: this
next = this%val
this%val = this%val + 1
end function
function raw(this) result(res)
class(Counter_t), target, intent(in) :: this
integer, pointer :: res
! This would be forbidden
! this%val = 5
res => this%val
end function
end module
program test_raw
use counter_mod, only: Counter_t
implicit none(type, external)
type(Counter_t), target :: c
integer, pointer :: ptr
write(*, *) c%next()
write(*, *) c%next()
ptr => c%raw()
ptr = 0
write(*, *) c%next()
end program