0

定数式、パラメーター パック、ラムダ、ムーブ セマンティクス、標準コンテナー、および std::any を使用すると、次のデザイン パターンを簡単に作成できます。

#include <utility>
#include <vector>
#include <any>

constexpr auto assign_properties = [](auto&&... t) { 
    return std::vector<std::any>{ std::move(t)... };  
};  

structこれにより、またはclassオブジェクトを定義する必要なく、プロパティまたは属性の任意のリストが作成されます。

簡単に言えば、次の方法で使用できます。

{
     auto props = assign_properties(1, 3.1f, 6.4, 'a');
}

ここで、このコンテナー内のタイプ セーフなデータにアクセスするには、各要素の型を事前に知っておく必要があり、次の方法でそれらを抽出する必要があります。

{
    auto a = std::any_cast<int>( props[0] );
    auto b = std::any_cast<float>( props[1] );
    auto c = std::any_cast<double>( props[2] );
    auto d = std::any_cast<char>( props[3] );
}

わかりました、これは単純で十分に公平です...

ポリモーフィックな動作を保持するクラス階層内に、このような何らかのメカニズムを組み込みたいとしましょう...

クラス階層内で、すべての型の派生元となる抽象基本型が必要になる場合があります。各派生クラスまたはサブクラスには、その動作または状態を説明する一連のプロパティまたは属性が含まれる場合がありますが、各サブクラスには、さまざまなタイプのさまざまな量の属性が含まれる場合があります...

例えば:

class Animal {
protected:
    Animal(); // Abstract
    std::vector<std::any> attributes_;
};
     
class Cat : public Animal {  
public:
    // ...    
};

class Dog : public Animal {
public:
   // ...
};

class Eagle : public Animal {
public:
   // ...
};

さて、ここではポリモーフィックな動作、仮想、または純粋な仮想メソッドを示していません。これは、簡単に説明する質問の意図には必要ないためです...他のコード内の別の場所で、これらのオブジェクトが作成され、その後、人口...

struct Fur;    
struct Fangs;
struct Claws;
struct Feathers;
struct Talons;
struct Scales;

{
   Cat c1;
   c1.populate_attributes(assign_properties( "Fluffy", 9, Fur, Fangs, Claws));

   Dog d1;
   d1.populate_attributes(assign_properties( "Ruff", 3, Fur, Fangs, Claws ));
   
   Eagle e1;
   e1.populate_attriutes(assign_properties( Fangs, Claws, Feathers, Talons );
}

十分に単純です... さて、上で述べたように、これらのベクトル内の値にアクセスするには、ある方法でその値を抽出するために使用するために、事前std::anyに知る必要があります。typestd::any_casttype-safe

ファイルを解析してクラスのデータ型を作成し、それらのプロパティを設定するときにこれを使用することを計画しているとしましょう。次に、他の関数またはコードブロックのどこかで、これらの要素にアクセスする必要があり、それらのタイプが何であるかわかりません...std::anyこのコンテキストでは、機能を提供したり、このプロセスを助けたりしません。

{ 
    std::vector<Animals*> animals { Constructed & Populated; }
}
// some other code block
{
    auto a, b, c, d, ...;
    a = animals[0];
    b = animals[1];
    c = animals[2];
    d = animals[3];
    
    // Above we got each individual animal from our external source vector...
    
    auto e,f,g,h, ...;
    e = a[0]; // doesn't give the type and its value, e will be `std::any`.
    e = std::any_cast<auto>( e[0] ); // will fail to compile since `<T>` must
                                     // be known at compile time.
    e = std::any_cast<?>( e[0] );    // ... and this is where I'm stuck
                                     // I need some form of extraction here!
                                     // and I would like for it to be automatic and generic.
}        

typesユーザーが事前にわからず、type-safeコンテキスト内でこれらの値にアクセスする必要がある場合、上記の現在の実装でこの取得または抽出プロセスを自動化する簡単な方法はありますか? そうでない場合、上記のコードを変更して意図したとおりに機能させるために何ができるか、またはこれの代わりに使用して、私が持っている動作を維持または提供しながら同様のデザインパターンを実装できる他のメカニズムまたは構造はありますか?表現?

4

0 に答える 0