为什么 std::is_same 不起作用

Why std::is_same does not work?

本文关键字:same 不起作用 is std 为什么      更新时间:2023-10-16

我的代码片段是:

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在某些

其他语言中没有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_streaminput_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引用接受流。另外,我认为您的"阅读"逻辑不正确。你不仅泄漏了分配new的内存,我非常怀疑你的意思是分配一个sizeof(not_pod_struct) not_pod_struct数组。

此代码

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

您还可以使用完整的模板规范,并在使用input_stream或output_stream以外的其他参数调用序列化时引发异常。这接近您的原始代码。

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