假设我想包装一些原始数据类型,同时让编译器利用“原始”数据的性质。如果没有构造函数,wrapped
项将按照预期使用memset()
/ memcpy()
进行简单地初始化和复制(clang 8.0.0,x86-64上的gcc 8.3)。
struct wrapped
{
constexpr wrapped() noexcept: n{0} {}
unsigned int n;
};
wrapped *clone(wrapped const *const ptr, std::size_t const sz)
{
wrapped *const result{new wrapped[sz]{}};
std::copy_n(ptr, sz, result);
return result;
}
一旦我提供了一个构造函数(如上所示,或者为n
提供了一个类内初始化),编译器生成的代码就会爆炸成111行(111 8.0.0) ),包括展开的复制循环,而不是对memcpy()
的简单调用。 gcc 8.3中的结果并不那么长,但是也不再利用memcpy()
了。
我是否可以做些什么使编译器认识到该类型仍然可以“简单地复制”?我曾经尝试过constexpr
和noexcept
的三度法则和-fives,但都没有成功。
请注意,此行为与wrapped
是POD无关(仅),因为定义析构函数也意味着该类型不是POD,但不会导致此编译器行为。