【发布时间】:2015-06-09 15:50:29
【问题描述】:
我有一个表示二进制消息的结构。我想编写一个函数来从缓冲区中获取下一条这样的记录(无论是文件还是套接字,都无所谓):
template <typename Record>
Record getNext();
现在,我可以这样写:
template <typename Record>
Record getNext() {
Record r;
populateNext(reinterpret_cast<char*>(&r), // maybe ::read()
sizeof(r)); // or equivalent
return r;
}
这很好,让我受益于 RVO。但是,它将调用Record 的默认构造函数,它可能由具有非平凡默认构造函数的类型组成,这些构造函数确实可以避免我想避免的工作 - 这些不一定是 POD 类型,但它们是 em> 标准布局。
有没有办法编写getNext(),这样我们就可以避免Record 上的任何构造函数(默认或复制/移动)?理想情况下,当用户调用时:
auto record = getNext<Record>();
缓冲区直接读入record的内存。这可能吗?
【问题讨论】:
-
出于好奇,您为什么要避免通过引用传递记录?实施要求?
-
可以说,您需要 trivially copyable 从字节数组复制到对象(以恢复其值而不是 UB)。如果对象是可简单复制的,则编译器可能会省略复制 ctor,即使它不属于复制省略异常。
-
@Columbo 我真的不知道。取决于您对 fine 的含义。我确信它需要使用 trivially copyable 类型。有讨论说这里trivially copyable太严格了,具体细节我记不得了。
-
@dyp Pablo 没有从 Chandler 那里听到任何关于磁盘调配的消息,他的想法只是关于破坏性移动优化。他说 noop 构造函数已经死了,他无意恢复这个话题。