[英]Mapping an enum to a template type
我有一個類型ValueWrapper
,它可以存儲由枚舉標識的幾種值類型之一:
enum class Type : uint32_t
{
Float = 0,
String,
// etc
};
struct ValueWrapper
{
ValueWrapper(float f)
: type{Type::Float},data{std::make_shared<float>(f)}
{}
ValueWrapper(std::string str)
: type{Type::String},data{std::make_shared<std::string>(str)}
{}
Type type;
std::shared_ptr<void> data;
};
現在我想定義一堆以ValueWrapper
作為參數並將實際值重定向到另一個 function 的函數,例如:
void print(const ValueWrapper &v)
{
switch(v.type)
{
case Type::Float:
std::cout<<*static_cast<float*>(v.data.get());
break;
case Type::String:
std::cout<<*static_cast<std::string*>(v.data.get());
break;
}
}
size_t size_of(const ValueWrapper &v)
{
switch(v.type)
{
case Type::Float:
return sizeof(float);
case Type::String:
return sizeof(std::string);
}
}
template<typename TFrom>
bool is_convertible(Type tTo)
{
switch(tTo)
{
case Type::Float:
return std::is_convertible_v<TFrom,float>;
case Type::String:
return std::is_convertible_v<TFrom,std::string>;
}
}
問題是,我有很多類型和功能,我寧願不必為每一個都做一個過長的 switch-case。
有沒有什么方法可以用現代 C++ 代替(偽代碼)做這樣的事情,所以我只需要做一次 switch-case 來確定實際類型嗎?:
type TO_TEMPLATE_TYPE(Type t)
{
switch(t)
{
case Type::Float:
return float;
case Type::String:
return std::string;
}
}
template<typename TFrom>
bool is_convertible(Type tTo)
{
return std::is_convertible_v<TFrom,TO_TEMPLATE_TYPE(tTo)>;
}
改用using ValueWrapper=std::variant<double,std::string,...>
。
void print(const ValueWrapper &v)
{
std::visit([](auto const& val){ std::cout<<val; }, v );
}
如果您想要共享所有權邏輯,請將其設為共享 ptr 的變體,或將其設為變體的共享 ptr。
我的意思是,你可以重新發明輪子,但為什么呢?
如果您完全反對更改布局,那么我要做的下一件事就是制作
template<class T>struct tag_t{using type=T;};
template<class T>constexpr tag_t<T> tag={};
tag_t<double>
etc, map enum 手動到variant,然后使用visit獲取tag_t<T>
std::variant<tag_t<double>,tag_t<std::string>> get_tag(Type e){
switch (e){
case Type::Float: return tag<double>;
case Type::String: return tag<std::string>;
}
}
ETC
void print(ValueWrapper const& v){
auto tag=get_tag(v.type);
std::visit([&](auto tag){
using T=decltype(tag)::type;
T* p=static_cast<T*>(v.data.get());
std::cout<<*p;
}, tag);
}
這種技術比手動操作要容易 100 倍; 我都做過。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.