【问题标题】:Generic typecasting通用类型转换
【发布时间】:2019-07-26 09:20:55
【问题描述】:

我使用的是 C++14(不能使用高于此的)。

我有 3 个结构:

struct TypeA {                    
    Header header;
    struct data {
        std::uint32_t d;                                           
    };
};

struct TypeB {                    
    Header header;
    struct data {
        std::uint32_t d;         
        std::uint16_t a;        
    };
};

struct TypeC {                    
    Header header;
    struct data {
        std::uint32_t d:20;     
        std::uint32_t a:12;     
    };
};

我还有一个字符串,它基本上是从流中接收的数据。解析头部(第一个 60 字节)后,我知道字符串的其余部分包含什么类型的数据(无论是 TypeA、TypeB 还是 TypeC)。最终我应该能够做类似的事情:

//header.type = 1, 2 or 3
data_type = get_data_type(header.type);
data_type data = static_cast<data_type>((char*)str.c_str());;

如何在不使用太多 if-else 语句的情况下以通用方式执行此操作?

【问题讨论】:

  • 有许多用于反序列化的库。如果您自己编写,则必须在某处切换类型,尽管我不明白您为什么害怕“ if-else 太多”,但我认为您确实需要一个,不是吗?
  • 我认为没有必要实际投射任何东西。只需阅读一个裸标题(它出现的真正原因......在 head ......是为了帮助识别它即将到来的内容。一旦你有了标题,有条件地创建你知道的任何内容从那里开始前进,可能会将预读标题移动到您现在已知的正在构建的对象中)。当然,你可以抽象它,但除非有几十种这样的类型,否则何必费心呢。
  • 自动数据有什么问题;而不是 data_type data = static_cast((char*)str.c_str());
  • @WhozCraig,是的,是Header,现在改了
  • 简短回答:你不能,因为 C++ 是静态类型的,你不能将数据类型存储在变量中。无论如何,您都需要某种 f 构造来对收到的数据采取行动

标签: c++ casting c++14 generic-programming type-deduction


【解决方案1】:

要没有 if 语句,您需要一个工厂函数的查找表(或 switch 语句)。根据您希望它有多“好”,您可以在运行时初始化表,也可以让编译器通过一些静态初始化魔法为您生成它。

运行时版本类似于:

using prefix_t = decltype(Header.type);
using myvar_t = std::variant<StructA, StructB, StructC>;
using factory_t = std::function<myvar_t(body_buffer_t)>;
std::map<prefix_t, factory_t> factories;

// this can be improved with static initialization so factories would register themselves
factories[HeaderOfStructA] = ...;
factories[HeaderOfStructB] = ...;
factories[HeaderOfStructC] = ...;

【讨论】:

  • 有趣的选项。
猜你喜欢
  • 1970-01-01
  • 2011-02-13
  • 2013-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-11
相关资源
最近更新 更多