更新

useしないと外部パッケージの比較演算子が見えない件

OOPの解説をprivateで書くべきかlimited privateで書くべきか悩みながら色々居試してたら、なんか困った現象にぶち当たってしまった。普段use使いまくりだから気がつかなかった。

withしたパッケージ内で宣言したレコードとか配列を=で比較しようと思うとコンパイルエラーが出る。withだけじゃなくて、インラインで宣言したパッケージでも発生するので、とりあえずサンプルコードを。

procedure Sample is
   package Test is
      -- 何でも良いから型宣言
      type Foo is array(Integer range 1 .. 0) of Integer;
   end Test;

   -- 同じ内容の型を宣言
   type Bar is array(Integer range 1 .. 10) of Integer;

   -- 比較するだけだから内容は何でもいい
   X : Test.Foo := (others => 1);
   Y : Test.Foo := (others => 1);

   N : Bar := (others => 1);
   M : Bar := (others => 1);

begin
   -- 当然いける
   if N = M then
      null;
   end if;

   -- これエラー
-- if X = Y then
--    null;
-- end if;

   -- use すれば使えるらしい
   declare
      use Test;
   begin
      if X = Y then
         null;
      end if;
   end;

end Sample;

エラーが出る部分のコメントを外してコンパイルすると、

operator for type "Foo" defined at sample.adb:4 is not directly visible
use clause would make operation legal

とか言われてコンパイルできない。言われたとおりにuseするとコンパイルできるんだけど、useが使えないときはどうするのよ!

Test.=

とか無理だし、どうしろと。思わずISO規格の本まで引っ張り出してきたけど、ここら辺のことなんか今一書いてないっぽい。派生型作っちゃえば比較演算子もインポートされるらしいけど、それもなんか違う気がするしなぁ。どうしたものか。

あるいは、明示的に演算子をオーバーロードしろってことなのかなぁ。でもそれだったらuseした時だけ可視になるのは納得いかないし。

この問題はAda95で導入されたuse typeで解決したらしい。

もの凄い勢いで読み飛ばしてた……。まさか真下に解決策があるとは思わなかったというか、ちゃんと表題付けといて欲しいなぁ。