std::uninitialized_copy
复制到未初始化的内存范围内。
对于按位可复制类型,可以使用memmove
来完成此操作。
我介绍了gdb中的示例代码(使用gcc 5.2.0进行编译)。
因此,我发现根本没有使用memmove
。
在示例__is_trivial(Bar)
中用于确定是否可以使用memmove
。
它(正确)评估为false
,因为Bar
有一个非平凡的默认构造函数(参见std::__uninitialized_copy<false>::__uninit_copy(...)
行bits/stl_uninitialized.h
ff中的123
调用。
但为什么__is_trivial
甚至与std::uninitialized_copy
相关?
根据{{3}} Bjarne应该足够了。请注意,后者在示例中评估为true
,即。 memmove
优化std::is_trivially_copyable
。
我知道,该标准不需要std::uninitialized_copy
的任何具体实现。我只是想知道为什么__is_trivial
受到青睐,即使std::is_trivially_copyable
作为gcc实施的适用替代品存在?
示例代码:
#include <iostream>
#include <memory>
#include <vector>
#include <type_traits>
struct Bar
{
Bar () : v(42) {};
Bar(Bar const &) = default;
Bar(Bar &&) = default;
Bar & operator=(Bar &&) = default;
Bar & operator=(Bar const &) = default;
~Bar() = default;
int v;
};
int main() {
std::cout
<< std::is_trivially_move_constructible<Bar>::value
<< " " << std::is_trivially_copy_constructible<Bar>::value
<< " " << std::is_trivially_copyable<Bar>::value
<< " " << std::is_trivial<Bar>::value
<< " " << __is_trivial(Bar) << std::endl;
size_t const num_elements = 1 << 27;
std::vector<Bar> v(num_elements);
Bar * vc = (Bar *) std::malloc(num_elements * sizeof(Bar));
std::uninitialized_copy(v.begin(), v.end(), vc);
std::free(vc);
}
示例输出:1 1 1 0 0
更新:我们进行了一些测试,比较memmove
,uninitialized_copy
和简单for
循环的实际运行时间。如果Bar
是微不足道的(参见__is_trivial(Bar)
),则uninitialized_copy
与memmove
一样快,如果不是,uninitialized_copy
与for
一样快循环。总体memmove
在2x
小{{更改Bar
到int v;
}上的速度明显加快(char v;
)。否则表现基本相同。
修改:更正std::is_trivially_...
的引用。更确切地说是州名。