问题描述
我最近在 this question 上询问过这个问题。我已经采用了这种通用方法:
#define COFFEE_GEN_GENERIC_VALUE(CLASS_TYPE) using GenericValue##CLASS_TYPE = coffee::utils::GenericValue<CLASS_TYPE,COFFEE_GENERIC_VALUE_CONFIG_MAX_DERIVED_SIZE_OF_##CLASS_TYPE>
template<typename Base,size_t MaxDerivedSize>
class GenericValue
{
private:
char buffer[MaxDerivedSize];
public:
GenericValue() = default;
template<typename Derived,typename... ConstructorArgs>
static GenericValue<Base,MaxDerivedSize> create(ConstructorArgs... args)
{
static_assert(std::is_base_of<Base,Derived>::value,"Derived must derive from Base.");
static_assert(sizeof(Derived) <= MaxDerivedSize,"The size specified with the macro COFFEE_GenericValueMaxSize is to small.");
GenericValue<Base,MaxDerivedSize> result{};
new ((Derived*) result.buffer) Derived{args...};
return result;
}
template<typename Derived>
static GenericValue<Base,MaxDerivedSize> from(Derived* toCopy)
{
static_assert(std::is_base_of<Base,"Derived must derive from Base.");
static_assert(sizeof(Derived) <= sizeof(MaxDerivedSize),MaxDerivedSize> result{};
memcopy(result.buffer,toCopy,sizeof(Derived));
return result;
}
GenericValue(const GenericValue<Base,MaxDerivedSize>& other)
{
memcopy(buffer,other.buffer,MaxDerivedSize);
}
GenericValue(GenericValue<Base,MaxDerivedSize>&& other)
{
memcopy(buffer,MaxDerivedSize);
}
GenericValue<Base,MaxDerivedSize>& operator=(const GenericValue<Base,MaxDerivedSize);
return *this;
}
GenericValue<Base,MaxDerivedSize>& operator=(GenericValue<Base,MaxDerivedSize>&& other)
{
coffee::utils::copy(buffer,MaxDerivedSize);
return *this;
}
Base& operator*()
{
return *(Base*)buffer;
}
Base* operator->()
{
return (Base*)buffer;
}
}
我对这种形式 this website 有想法,它与@Matthias Grün 在我的旧问题上的 awnser 类似。
您使用 COFFEE_GEN_GENERIC_VALUE
宏为 GenericValue<Base,MaxDerivedSize>
创建一个 typedef,大小将通过第二个宏传递给它。这样我的库就可以生成将用于特定基类的适当 GenericValue
类型。它背后的基本思想是将派生类型的整个实例及其 vtable 存储在 buffer
中。您可以像复制常规右值一样复制它。
不幸的是,复制只在某些时候有效,我不知道为什么,根据我的知识,这不会成为问题。如果我删除复制运算符和构造函数,并仅使用该类作为 new
的包装器,它会很好地工作(除非对象并未真正复制)。
有没有人知道可能是什么问题?
当我发现一个不需要发布整个项目的边缘案例时,我会发布一个具体示例。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)