Ada中动态数组的索引器和引用类型 [英] Indexer and reference type for dynamic arrays in Ada

查看:70
本文介绍了Ada中动态数组的索引器和引用类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下规格:

generic
    type Value_Type is private;
package Containers.Arrays is

    type Static_Array is array(Positive range <>) of Value_Type;
    type Static_Array_Access is access all Static_Array;

    type Dynamic_Array is tagged private;

    function Length(Self : Dynamic_Array) return Natural with Inline;

    function "&"(Left : Dynamic_Array; Right : Value_Type) return Dynamic_Array;

private
    type Dynamic_Array is tagged record
        Backing : Static_Array_Access;
    end record with
        Variable_Indexing => Variable_Indexer;

    type Variable_Reference(Data : access Value_Type) is null record with
        Implicit_Dereference => Data;
    function Variable_Indexer(Self : Dynamic_Array; Index : Positive)
        return Variable_Reference with Pre => Index <= Self.Length;

下面是Variable_Indexer的实现:

Along with an implementation of Variable_Indexer as follows:

function Variable_Indexer(Self : Dynamic_Array; Index : Positive)
    return Variable_Reference is
begin
    return Variable_Reference(Data => new Value_Type'(Self.Backing(Index)));
end Variable_Indexer;

我已经知道了这里的问题,但是我仍然会给出测试代码并解释会发生什么情况.

I know the problem here already, but I'll still give my test code and explain what happens.

DA : Dynamic_Array := 'a' & 'b' & 'c';
pragma Assert(DA.Length = 3);
pragma Assert(DA(1) = 'a');
pragma Assert(DA(2) = 'b');
pragma Assert(DA(3) = 'c');

到目前为止一切正常

DA(1) := 'A'; --Change to majiscule from miniscule
pragma Assert(DA(1) = 'A'); --fails

我知道这是因为Variable_Indexer没有引用DA(1),而是实际上在堆上分配了一个恰好具有DA(1)值的新变量.我想我需要给该值加上别名并返回对该别名的访问权限.但是,我一直无法得到这样的东西来进行编译,更不用说工作了.

I know this is because Variable_Indexer didn't reference DA(1), but actually allocated a new variable on the heap with the value that DA(1) just so happened to have. I figure I need to alias the value and return an access to the alias. I, however, have been unable to get such a thing to compile, let alone work.

推荐答案

感谢@ajb,因为我完全忘记了为数组的元素添加别名.

Thanks to @ajb for this one, as I completely forgot about aliasing the elements of an array.

将Static_Array更改为:

Change Static_Array to:

type Static_Array is array(Positive range <>) of aliased Value_Type;

并将Variable_Indexer更改为:

and change Variable_Indexer to:

function Variable_Indexer(Self : Dynamic_Array; Indexer : Positive) return Variable_Reference is
begin
    return Variable_Reference'(Data => Self.Backing(Index)'Access);
end Variable_Indexer;

现在,它不再在堆上创建新值并返回指向该值的指针,而是返回指向数组中元素的指针;这是正确的行为.

Now, instead of creating a new value on the heap, and returning a pointer to that, it now returns a pointer to the element in the array; this is proper behavior.

这篇关于Ada中动态数组的索引器和引用类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆