wvn*_*wvn 6 c++ static-reflection
我正在开发一个大量使用静态多态性的项目。我感兴趣的一个特定用例可以通过静态反射来实现,但我们在 C++ 中仍然没有这种功能。用例看起来像这样:我有一个函数可以从二进制文件读取/写入数据结构:
template <typename data_t> void write_binary(const my_type_t<data_t>& obj)
{
//write a binary file...
}
template <typename data_t> void read_binary(my_type_t<data_t>& obj)
{
//read a binary file...
}
Run Code Online (Sandbox Code Playgroud)
我想强制我只能从相同类型输出的文件中读取数据,例如my_type_t<std::string>只能从 等输出的二进制文件中读取数据my_type_t<std::string>。我想要执行此操作的方法是向二进制文件添加一个小标头确定了 的专业化data_t:
template <typename data_t> void write_binary(const my_type_t<data_t>& obj)
{
//write header type_name(data_t)
//write a binary file...
}
template <typename data_t> void read_binary(my_type_t<data_t>& obj)
{
//read header
//assert header == type_name(data_t)
//read a binary file...
}
Run Code Online (Sandbox Code Playgroud)
我知道它的存在typeid(data_t).name()以及分解它的各种方法,但我想要由标准定义的东西。
所以我的确切问题是:对于任何两种类型type1_t和type2_t,是否存在任何 C++ 标准定义的映射“F”,无论它F(type1_t) == F(type2_t)总是暗示type1_t == type2_t,并且type1_t == type2_t总是暗示F(type1_t) == F(type2_t),独立于编译器?也就是说,类型和 C++ 标准定义的某种可序列化值之间是否存在双射映射?
编辑
这个问题有一个微妙之处,我最初没有强调:我不想序列化任意类型。将我的对象写入文件的函数体已经实现。我想要的(如上面的问题所述)只是每个独立于编译器的类型的唯一标识符。data_t模板特化的作用my_type_t<data_t>不是影响写入/读取哪些信息,而是影响如何解释信息。
还有其他几个主题点:
data_t,我必须允许它可以是任何类型。data_t最终用于 I/O 的最终类型与用户所接触的接口无关。不。
问题似乎也没有从中受益。序列化在 C++ 中通常是不可能的,因此无论您实现它们还是您的用户进行序列化和反序列化,您都将拥有自定义点,并且它们将是特定于类型的。换句话说,在:
template <typename data_t> void write_binary(const my_type_t<data_t>& obj)
{
//write header type_name(data_t)
//write a binary file...
}
Run Code Online (Sandbox Code Playgroud)
必须write a binary file具体到data_t。必须存在写 astd::string与 a 不同的情况int。如果需要,每种情况都可以在前面添加一个标识标头。反序列化可以检查该标头。反序列化还可以检查该类型的其他不变量。
要求人们为其类型实现某种“名称”字段
自定义点不需要特定字段。有一些方法可以允许非侵入性地自定义行为,例如模板专门化(特征)和 ADL(重载)。
类型本身的名称最终只是源代码的属性
类型是源代码的属性。名称和拼写是类型的特定格式的选择。type_id(x).name()是一种格式选择,在不同的编译器上会有所不同。另一种是分解后的名称,它在不同的平台上会有所不同。分解后的名称不一定是唯一的。
(最后,使用类型名称来标识序列化值很可爱,但可能会产生惊喜。例如,人们通常期望能够重命名类类型而不影响序列化数据。人们通常期望将其移动到新的命名空间,即使在旧位置使用 typedef 也能将影响降到最低,而不影响序列化数据。)
| 归档时间: |
|
| 查看次数: |
152 次 |
| 最近记录: |