ฉันใช้แม่แบบต่อไปนี้เพื่อใช้การทำให้เป็นอันดับ:
template <class T, class Mode = void> struct Serializer
{
template <class OutputCharIterator>
static void serializeImpl(const T &object, OutputCharIterator &&it)
{
object.template serializeThis<Mode>(it);
}
template <class InputCharIterator>
static T deserializeImpl(InputCharIterator &&it, InputCharIterator &&end)
{
return T::template deserializeFrom<Mode>(it, end);
}
};
template <class Mode = void, class T, class OutputCharIterator>
void serialize(const T &object, OutputCharIterator &&it)
{
Serializer<T, Mode>::serializeImpl(object, it);
}
template <class T, class Mode = void, class InputCharIterator>
T deserialize(InputCharIterator &&it, InputCharIterator &&end)
{
return Serializer<T, Mode>::deserializeImpl(it, end);
}
template <class Mode = void, class T, class InputCharIterator>
void deserialize(T &result, InputCharIterator &&it, InputCharIterator &&end)
{
result = Serializer<T, Mode>::deserializeImpl(it, end);
}
นี่T
คือประเภทที่คุณต้องการทำให้Mode
เป็นอนุกรมเป็นประเภทหุ่นที่จะแยกแยะความแตกต่างระหว่างชนิดของการทำให้เป็นอนุกรมเช่น จำนวนเต็มเดียวกันสามารถต่อเนื่องเป็น endian น้อย, endian ใหญ่, varint ฯลฯ
โดยค่าเริ่มต้นSerializer
ผู้รับมอบสิทธิ์งานไปยังวัตถุที่เป็นอนุกรม สำหรับประเภทบิวด์อินคุณควรสร้างเทมเพลตเฉพาะSerializer
สำหรับ
มีฟังก์ชั่นแม่แบบอำนวยความสะดวก
ตัวอย่างเช่นการเรียงลำดับ endian เล็กน้อยของจำนวนเต็มที่ไม่ได้ลงนาม:
struct LittleEndianMode
{
};
template <class T>
struct Serializer<
T, std::enable_if_t<std::is_unsigned<T>::value, LittleEndianMode>>
{
template <class InputCharIterator>
static T deserializeImpl(InputCharIterator &&it, InputCharIterator &&end)
{
T res = 0;
for (size_t i = 0; i < sizeof(T); i++)
{
if (it == end) break;
res |= static_cast<T>(*it) << (CHAR_BIT * i);
it++;
}
return res;
}
template <class OutputCharIterator>
static void serializeImpl(T number, OutputCharIterator &&it)
{
for (size_t i = 0; i < sizeof(T); i++)
{
*it = (number >> (CHAR_BIT * i)) & 0xFF;
it++;
}
}
};
จากนั้นให้เป็นอันดับ:
std::vector<char> serialized;
uint32_t val = 42;
serialize<LittleEndianMode>(val, std::back_inserter(serialized));
ในการยกเลิกการย่อ:
uint32_t val;
deserialize(val, serialized.begin(), serialized.end());
เนื่องจากตรรกะตัววนซ้ำนามธรรมมันควรทำงานกับตัววนซ้ำใด ๆ (เช่นสตรีมตัววนซ้ำ) ตัวชี้ ฯลฯ