我正在使用"Tiny Template Library"中的变体类型。 Variant定义为:
template< TTL_TPARAMS_DEF(TTL_MAX_TYPELIST_PARAMS, empty_type) >
struct variant
{
typedef variant this_t;
typedef meta::typelist< TTL_ARGS(TTL_MAX_TYPELIST_PARAMS) > list;
...
template< typename T >
variant( const T& r ) : which_(0), pnt_(0)
{
typedef meta::find_equivalent_type<const T&, list> found;
pnt_ = new(stor_.buf_) ttl::data_holder<typename found::type>(r);
which_ = found::index;
}
...
private:
template<int N>
struct storage
{
union
{
ttl::data_holder_base dummy; //hope to satisfy alignment settings
char buf_[N];
};
};
int which_;
ttl::data_holder_base* pnt_;
storage< sizeof(ttl::data_holder<typename list::largest_type>) > stor_;
....
};
struct data_holder_base {};
template< typename T >
struct data_holder : data_holder_base
{
...
typedef const T& param_type;
T d;
...
data_holder( param_type d_ ) : d(d_) {}
...
};
当我通过网络发送这种类型的对象并使用“memcpy”“重建”它时,很明显指针“pnt_”将指向Nirvana。由于我知道存储的类型,我尝试使用强制转换重建指针“pnt_”:
template<typename T>
inline void rebuild()
{
pnt_ = reinterpret_cast<ttl::data_holder<T>*>(stor_.buf_);
}
对于我查看此示例的情况,它可以正常工作。但我不知道新的展示位置(pnt_ = new(stor_.buf_) ...
)如何将对象放入stor_.buf_
。
是否需要存储类似std::distance(&stor_.buf_[0], pnt_)
的内容才能找到对象?
或者有不同的方式让pnt_
回来吗?
谢谢 马里奥
答案 0 :(得分:0)
展示位置new
会将新对象置于stor_.buf_
中,因为这是定位new
的工作方式。您为new
提供了要使用的内存地址,并在该位置构造对象。它返回的地址完全相同,因此pnt_
中存储的地址是stor_.buf_
的地址,但是对于构造对象的类型ttl::data_holder<found::type>
,而不是char*
。由于地址相同,所以你提到的std::distance
值总是为零(假设调用甚至会编译,因为参数类型不同,所以不会这样)。
stor_.buf_
的地址也将始终等于stor_.dummy
的地址。您可以通过像这样分配pnt_
来简化添加的代码:
pnt_ = &stor_.dummy;
但是,由于你显然只是在套接字上复制了原始内存,修复这个variant
对象的内部只是冰山一角。您的变体所拥有的值可能也包含地址,而您无法进入其中。即使您这样做,您所需的地址也可能无法使用。您很幸运variant
您正在修复的地址恰好是同一对象中的地址,因此很容易计算。但请考虑std::string
,它从免费商店分配内存;通过套接字发送一个不会在另一端给你任何可用的东西 - 它甚至可能根本不会给你字符数据。您应该采用其他一些技术来序列化和反序列化ttl::variant
个对象。您可以在Stack Overflow上发布一个问题,询问如何操作。