gpt4 book ai didi

c++ - 实现一个对象目录:boost::any、boost::variant,或者?

转载 作者:太空狗 更新时间:2023-10-29 21:22:55 26 4
gpt4 key购买 nike

我想实现一个存储不同类型对象的目录对象。需要能够按名称访问对象,获取实际指针类型并将其序列化。我想到的对象如下所示:

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;
};

Typelist 对于不同的目录是不同的。然后,拥有 dirs 的 dir 将是 Typelist 的动态 union 。看起来很复杂。而且它很快就会达到 50 种变体类型的限制。替代方案是 Boost::Any 以简化语义。但我想迭代对象集,并对其进行操作——每个对象都是一个 boost::fusion adapt_struct——我想在每个对象的每个成员上进行 fusion::for_each 并显示它们,例如……有任何替代方案或建议吗?

最佳答案

一切都取决于有多少种不同的类型以及您需要什么样的性能。如果对象类型的数量有限,那么您最好使用通用基类,并为每种类型专门化。

下面的代码使用了 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");
}

关于c++ - 实现一个对象目录:boost::any、boost::variant,或者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19511405/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com