繁体   English   中英

为什么std :: is_same不起作用?

[英]Why std::is_same does not work?

我的代码段是:

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'

这很奇怪。 我不明白为什么会发生这些错误。

这段代码

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;
}

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>());
}

或者只是对output_streaminput_stream重载serialize

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了通过引用接受流。 另外,我认为您的“读取”逻辑不正确。 您不仅会泄漏分配给new的内存,而且我非常怀疑您是否打算分配一个sizeof(not_pod_struct) not_pod_struct数组。

您还可以使用完整的模板规范,并在使用不同于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));
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM