我的代码段是:
namespace serialization
{
struct output_stream
{
/////
void write(const void* data, size_t size)
{
const byte_t* p = static_cast<const byte_t*>(data);
size_t old_size = buffer_.size();
buffer_.resize(old_size + size);
memcpy(buffer_.data() + old_size, p, size);
}
}
struct input_stream
{
///////
void read(void* to, size_t size)
{
assert(cur_ + size <= end_);
memcpy(to, cur_, size);
cur_ += size;
}
}
}
template <class stream_t>
void serialize(not_pod_struct& r, stream_t stream)
{
if (std::is_same<stream_t, serialization::output_stream>::value)
{
stream.write(&r, sizeof(r));
}
else if (std::is_same<stream_t, serialization::input_stream>::value)
{
not_pod_struct* buf = new not_pod_struct[sizeof(not_pod_struct)];
stream.read(buf, sizeof(not_pod_struct));
r = *buf;
}
else
{
throw std::invalid_argument("stream_t is not a stream.");
}
}
template<class T>
typename enable_if<!is_pod<T>::value, void>::type
read(input_stream & input_stream, T & non_pod_struct)
{
serialize(non_pod_struct, input_stream);
}
template<class T>
typename enable_if<!is_pod<T>::value, void>::type
write(output_stream & output_stream, T & non_pod_struct)
{
serialize(non_pod_struct, output_stream);
}
我有错误:
Error 1 error C2039: 'read' : is not a member of 'serialization::output_stream'
Error 2 error C2039: 'write' : is not a member of 'serialization::input_stream'
这很奇怪。我不明白为什么会发生这些错误。
答案 0 :(得分:5)
此代码
if (std::is_same<stream_t, serialization::output_stream>::value)
{
stream.write(&r, sizeof(r));
}
else if (std::is_same<stream_t, serialization::input_stream>::value)
{
not_pod_struct* buf = new not_pod_struct[sizeof(not_pod_struct)];
stream.read(buf, sizeof(not_pod_struct));
r = *buf;
}
没有按你的想法行事。当函数模板serialize
被实例化时,其代码必须格式正确,但事实并非如此。考虑内部发生的事情,例如serialize<output_stream>
:
if (true)
{
stream.write(&r, sizeof(r));
}
else if (false)
{
// This branch never executes, but this doesn't mean it's not compiled!
not_pod_struct* buf = new not_pod_struct[sizeof(not_pod_struct)];
// And output_stream doesn't have read() method.
stream.read(buf, sizeof(not_pod_struct));
r = *buf;
}
答案 1 :(得分:5)
if
不是static if
。未到达的分支仍然必须编译。
标记调度(如果您正在执行比is_same
更复杂的事情(例如,接受基于is_input_stream
特征的各种流),这会更有用;在使用中没有太大意义一个模板,它只接受两种类型,并且每种类型完全不同的东西):
template <class stream_t>
void serialize(not_pod_struct& r, stream_t & stream,
std::true_type /* is_input */, std::false_type /* is_output */)
{
not_pod_struct* buf = new not_pod_struct[sizeof(not_pod_struct)];
stream.read(buf, sizeof(not_pod_struct));
r = *buf;
}
template <class stream_t>
void serialize(not_pod_struct& r, stream_t & stream,
std::false_type /* is_input */, std::true_type /* is_output */)
{
stream.write(&r, sizeof(r));
}
template <class stream_t>
void serialize(not_pod_struct& r, stream_t & stream)
{
serialize(r, stream, std::is_same<stream_t, serialization::input_stream>(),
std::is_same<stream_t, serialization::output_stream>());
}
或仅为serialize
和output_stream
{<1}}重载input_stream
:
void serialize(not_pod_struct& r, serialization::input_stream & stream)
{
not_pod_struct* buf = new not_pod_struct[sizeof(not_pod_struct)];
stream.read(buf, sizeof(not_pod_struct));
r = *buf;
}
void serialize(not_pod_struct& r, serialization::output_stream & stream)
{
stream.write(&r, sizeof(r));
}
我冒昧地让serialize
通过引用接受流。另外,我不认为你的阅读&#34;逻辑是正确的。您不仅泄漏了使用new
分配的内存,而且我非常怀疑您是否要分配sizeof(not_pod_struct)
not_pod_struct
的数组。
答案 2 :(得分:1)
您还可以使用完整模板规范,并在使用除input_stream或output_stream之外的其他参数调用serialize时抛出异常。 这与原始代码非常接近。
template<typename X>
void serialize(not_pod_struct & r, X & x)
{
throw std::invalid_argument("stream_t is not a stream.");
}
template<>
void serialize(not_pod_struct& r, serialization::input_stream & stream)
{
not_pod_struct* buf = new not_pod_struct[sizeof(not_pod_struct)];
stream.read(buf, sizeof(not_pod_struct));
r = *buf;
}
template<>
void serialize(not_pod_struct& r, serialization::output_stream & stream)
{
stream.write(&r, sizeof(r));
}