13.1.25.3 Anyからの抽出

型保障の方法でanyから値を取得できるようにするために、ORBではOMG IDLの型Tごとに次の演算子が用意されています:

// C++
Boolean operator>>=(const Any&, T&);

この関数シグネチャは、通常値渡しされるプリミティブ型には十分です。型Tの値が大きすぎて完全に値を渡すことができない場合、ORBでは次のように別のシグネチャが提供されます。

// C++
Boolean operator>>=(const Any&, T*&);

この関数の最初の形式は、次の型にのみ使用されます:

  • Boolean, Char, Octet, Short, UShort, Long, ULong, Float, Double
  • 列挙
  • 無制限文字列(参照によって渡されたchar*、つまりchar*&)
  • オブジェクト参照(T_ptr)

その他の型については、すべて関数の2番目の形式が使用されます。

前述の右シフト代入演算子は、次のように型付き値をanyから抽出するために使用します:

// C++
Long value;
Any a;
a <<= Long(42);
if (a >>= value) {
      // ... use the value ...
}

この場合、型Longoperator>>=のバージョンは、Anyが型Longの値を格納しているかどうかを判別します。格納している場合、呼出し側によって提供されたリファレンス変数にその値をコピーし、TRUEを返します。Anyが型Longの値を格納していない場合、呼出し側のリファレンス変数の値は変更されず、operator>>=FALSEを返します。

非プリミティブ型の場合、ポインタが抽出を行います。たとえば、次のOMG IDL構造体を考えます:

// IDL
struct MyStruct {
    long lmem;
    short smem;
};

このような構造体は、次のようにAnyから抽出できます:

// C++
Any a;
// ... a is somehow given a value of type MyStruct ...
MyStruct *struct_ptr;
if (a >>= struct_ptr) {
      // ... use the value ...
}

抽出に成功した場合、呼出し側のポインタはAnyが管理するストレージを指し、operator>>=TRUEを返します。呼出し側は、このストレージのdeleteまたは解放を試行する必要はありません。また、代入、挿入、またはreplace関数によってAny変数が置き換えられた後、またはAny変数が破棄された後は、呼出し側はストレージを使用してはなりません。ただし、これらの抽出演算子でT_var型を使用しないよう注意する必要があります。これは、Anyによって所有されるストレージを抽出演算子が削除しようとするためです。

抽出に失敗した場合、呼出し側のポインタの値はNULLポインタと同じに設定され、operator>>=FALSEを返します。

配列型を正しく抽出するには、Array_forany型を使用します。この型については、「配列」を参照してください。

次に、OMG IDLの例を示します:

// IDL
typedef long A[20];
typedef A B[30][40][50];
// C++
typedef Long A[20];
typedef Long A_slice;
class A_forany { ... };
typedef A B[30][40][50];
typedef A B_slice[40][50];
class B_forany { ... };
Boolean operator>>=(const Any&, A_forany&);                  // for
type A
Boolean operator>>=(const Any&, B_forany&);                 // for type
B

Array_forany型は、リファレンスによって常にoperator>>=に渡されます。

文字列および配列の場合、アプリケーションはAnyのTypeCodeをチェックします。これは、抽出値を使用する際に、アプリケーションが確実に配列オブジェクトまたは文字列オブジェクトの境界を越えないようにするためです。

operator>>=は、Any_var型でもサポートされます。