3

さまざまな種類のオブジェクトを格納するディレクトリ オブジェクトを実装したいと思います。名前でオブジェクトにアクセスし、実際のポインター型を取得してシリアル化できる必要があります。私が考えているオブジェクトは次のようになります。

struct Object {
    std::string name;
    SomeType ptr;
};
struct Dir {
  std::string name;
  std::set<Object> objects;
};

「SomeType」はBoost::variantを使おうと思っていました。しかし、実行時にオブジェクト タイプをバリアント リストに追加する必要があるようです。先のディレクトリのオブジェクトタイプを知っていても、

template <typename Typelist>
struct Object<Typelist> {
    std::string name;
    boost::variant<Typelist> objects;
};

whereTypelistはディレクトリごとに異なります。次に、dirs の dir を持つことは、Typelist の動的結合になります。複雑に見えます。そして、まもなく 50 のバリアント タイプの制限に達します。セマンティクスを簡素化するための代替手段は Boost::Any です。しかし、私はオブジェクトのセットを繰り返し処理したいと思います-各オブジェクトはboost::fusion adapt_structです-各オブジェクトの各メンバーでfusion::for_eachを行い、それらを表示したいと思います. 代替案や提案はありますか?

4

2 に答える 2

2

すべては、必要な種類とパフォーマンスの種類によって異なります。オブジェクト タイプの数が限られている場合は、タイプごとに特化した共通の基本クラスを使用することをお勧めします。

以下のコードはboost::shared_ptr、関連するキャスト機能を利用しています。boost::shared_dynamic_cast基本型と特殊型の間を行き来するために使用できます。

#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include <iostream>
#include <list>

namespace stackoverflow
{

struct base_object
{
    enum type_t
    {
        directory = 0, file, link,

        n_types
    };

    const std::string name;
    const type_t type;

    base_object(const std::string& name, const type_t& type) :
            name(name), type(type) {
    }

    virtual ~base_object()
    {
    }
};

struct file_object : public base_object
{
    file_object(const std::string& name) : base_object(name, base_object::file)
    {
    }
};

struct symlink_object : public base_object
{
    symlink_object(const std::string& name) : base_object(name, base_object::link)
    {
    }
};

struct directory_object: public base_object
{
    std::list<boost::shared_ptr<base_object> > children;

    directory_object(const std::string& name) :
            base_object(name, base_object::directory)
    {
    }

    template < typename TypeTag >
    boost::shared_ptr< typename TypeTag::object_type > add(const std::string& name);
};

template < typename ObjectType >
struct tag
{
    typedef ObjectType object_type;
};

typedef tag< directory_object > directory;
typedef tag< file_object > file;
typedef tag< symlink_object > symlink;

template < typename TypeTag >
boost::shared_ptr< typename TypeTag::object_type > directory_object::add(const std::string& name)
{
    return boost::shared_dynamic_cast< typename TypeTag::object_type , base_object >(
            *children.insert(children.end(),
                    boost::shared_dynamic_cast< base_object, typename TypeTag::object_type >(
                            boost::make_shared< typename TypeTag::object_type >(name))));
}

}  // namespace stackoverflow


int main(void)
{
    using namespace stackoverflow;

    boost::shared_ptr< directory_object > root = boost::make_shared< directory_object >("/");
    root->add<directory>("etc")
            ->add<file>("hosts");
    root->add<directory>("tmp")
            ->add<file>("something.tmp");
    root->add<directory>("var")
            ->add<directory>("lib")
                ->add<directory>("mysql");
}
于 2013-10-23T11:38:52.363 に答える