What is the no-undefined-behavior way of deserializing an object from a byte array in C++11 (or later)?

百般思念 提交于 2019-12-05 01:13:47

What you want is this:

T result;
char * p = reinterpret_cast<char *>(&result);   // or std::addressof(result) !

std::memcpy(p, ptr, sizeof(T));                 // or std::copy!!

return result;

No aliasing violation. If you want a T, you need to have a T. If your type is trivially copyable, then hopefully it is also trivially constructible and there is no cost. In any event, you have to copy the return operand out into the function return value, and that copy is elided, so there's really no extra cost here.

You want to use std::aligned_storage class template. It's been designed to handle this exact problem. Here's a sample solution with some SFINAE based upon your check in your question.

template<class T>
typename std::enable_if<std::is_trivially_copyable<T>::value, T>::type deserialize(const char *data) {
    typename std::aligned_storage<sizeof(T), alignof(T)>::type destination;
    std::memcpy(&destination, data, sizeof(T));
    return reinterpret_cast<T &>(destination);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!