这听起来可能很基本,但:
WORD wSong = 0;
CArchive ar;
...
ar >> wSong;
m_sPublicTalkInfo.iSongStart = static_cast<int>(wSong);
目前,我将WORD
读入一个特定的变量,并对其进行强制转换。
我能同时读一读吗?
请注意,我不能序列化一个int
。它必须是一个WORD
并转换为int
。或
ar >> wSong;
m_sPublicTalkInfo.iSongStart = static_cast<int>(wSong);
发布于 2019-11-07 02:06:49
我不认为有直接的办法。您可以实现一个助手函数:
template <typename T, typename U>
T readAndCast (CArchive& ar) {
U x;
ar >> x;
return static_cast<T> (x);
}
m_sPublicTalkInfo.iSongStart = readAndCast<int, WORD>(ar);
在您的程序中使用固定宽度整数类型可能更好,例如,也许int_least16_t
而不是int
,以确保类型具有正确的大小。WORD
是固定到16位,但是int
不是。另外,WORD
没有签名,int
没有签名,所以在转换过程中可能会出现溢出。
发布于 2019-11-07 16:08:03
这是一个示例,说明如果希望序列化语法保持一致,可以如何创建包装器。它只用于处理积分和MFC无符号类型。
#include <iostream>
#include <cstdint>
#include <sstream>
#include <type_traits>
// Fake the MFC types
using BYTE = std::uint8_t;
using WORD = std::uint16_t;
using DWORD = std::uint32_t;
using QWORD = std::uint64_t;
template<typename T>
struct is_valid_save_type : std::bool_constant<
std::is_same_v<BYTE, T> ||
std::is_same_v<WORD, T> ||
std::is_same_v<DWORD, T> ||
std::is_same_v<QWORD, T>
> {};
template<typename T>
struct is_valid_load_type : is_valid_save_type<T> {};
// Saves type T as a SaveType
template<typename T, typename SaveType>
struct save_as_type
{
explicit save_as_type(T value) : value(value) {}
explicit operator SaveType() const
{
return static_cast<SaveType>(value);
}
private:
T value;
// This class only works with integrals
static_assert(std::is_integral_v<T>);
// SaveType should be BYTE/WORD/DWORD/QWORD only
static_assert(is_valid_save_type<SaveType>::value);
};
// Loads type T as a LoadType
template<typename T, typename LoadType>
struct load_as_type
{
explicit load_as_type(T& value) : value_(value) {}
load_as_type& operator=(LoadType rhs)
{
value_ = rhs;
return *this;
}
private:
T& value_;
// T should be an integral
static_assert(std::is_integral_v<T>);
// T must be non-constant
static_assert(!std::is_const_v<T>);
// LoadType should be BYTE/WORD/DWORD/QWORD only
static_assert(is_valid_load_type<LoadType>::value);
};
class CArchive;
// Make the above types serializable
template<typename T, typename SaveType>
CArchive& operator<<(CArchive& ar, save_as_type<T, SaveType> const& s)
{
ar << static_cast<SaveType>(s);
}
template<typename T, typename LoadType>
CArchive& operator>>(CArchive& ar, load_as_type<T, LoadType> l)
{
LoadType t{};
ar >> t;
l = t;
}
// Use the following two functions in your code
template<typename SaveType, typename T>
save_as_type<T, SaveType> save_as(T const& t)
{
return save_as_type<T, SaveType>{ t };
}
template<typename LoadType, typename T>
load_as_type<T, LoadType> load_as(T& t)
{
return load_as_type<T, LoadType>{ t };
}
// Prevent loading into temporaries; i.e. load_as<BYTE>(11);
template<typename T, typename LoadType>
load_as_type<T, LoadType> load_as(const T&& t) = delete;
// Fake MFC Archive
class CArchive
{
public:
CArchive& operator<<(int i)
{
std::cout << "Saving " << i << " as an int\n";
return *this;
}
CArchive& operator<<(BYTE b)
{
std::cout << "Saving " << (int)b << " as a BYTE\n";
return *this;
}
CArchive& operator<<(WORD w)
{
std::cout << "Saving " << (int)w << " as a WORD\n";
return *this;
}
CArchive& operator<<(DWORD d)
{
std::cout << "Saving " << (int)d << " as a DWORD\n";
return *this;
}
CArchive& operator>>(int& i)
{
std::cout << "Loading as an int\n";
return *this;
}
CArchive& operator>>(BYTE& b)
{
std::cout << "Loading as a BYTE\n";
return *this;
}
CArchive& operator>>(WORD& w)
{
std::cout << "Loading as a WORD\n";
return *this;
}
CArchive& operator>>(DWORD& d)
{
std::cout << "Loading as a DWORD\n";
return *this;
}
};
int main()
{
CArchive ar;
int out_1 = 1;
int out_2 = 2;
int out_3 = 3;
int out_4 = 4;
ar << out_1 <<
save_as<BYTE>(out_2) <<
save_as<WORD>(out_3) <<
save_as<DWORD>(out_4);
std::cout << "\n";
int in_1 = 0;
int in_2 = 0;
int in_3 = 0;
int in_4 = 0;
ar >> in_1 >>
load_as<BYTE>(in_2) >>
load_as<WORD>(in_3) >>
load_as<DWORD>(in_4);
return 0;
}
输出:
将1保存为int
将2保存为字节
保留3作为一个词
将4保存为DWORD
作为int加载
以字节形式加载
加载为一个词
作为DWORD加载
https://stackoverflow.com/questions/58746123
复制相似问题