编辑: this似乎完全解决了我的问题。
关于Which type trait would indicate that type is memcpy assignable? (tuple, pair)
答案是std::is_trivially_copyable
可以告诉我是否可以安全地memcpy
围绕我的对象。
现在考虑:
#include <iostream>
#include <type_traits>
struct A {
int x;
int y;
A(const A& other) : x(other.x), y(other.y){}
};
struct B {
int x;
int y;
B(const B& other) = default;
};
int main()
{
std::cout << std::boolalpha;
std::cout << std::is_trivially_copyable<A>::value << '\n'; //false
std::cout << std::is_trivially_copyable<B>::value << '\n'; //true
}
A
和B
对所有实际效果都相同,但A
被检测为不可轻易复制。
那么,我会在memcpy
这样的对象中接受哪种风险呢?
用例:我希望在opencv库中有vector
的动态数组(不是realloc
,我会用cv::Point
增长),这可能是因为C ++ 98兼容性不使用default
来定义复制构造函数。
答案 0 :(得分:0)
主要风险是优化器彻底删除了对memcpy
的调用。这是一个非常合理的优化:最快的代码是未调用的代码,并且可以安全地假设代码未使用不正确的参数调用。
这也会带来第二个风险:优化器不仅可以删除memcpy
调用,而且所有代码都不可避免地导致它。它可以回溯到前面的if
语句,观察哪个分支通向memcpy
,并且只删除整个分支和测试条件。
答案 1 :(得分:0)
编译器看到你有一个复制构造函数并退出。它并不关心其中的内容,但是如果编译器检测到分配没有为默认值添加任何内容的简单情况会很好。
在这种特殊情况下,你可以逃脱它,没有真正的伤害
另一方面,你为下一个开发者留下维护噩梦
你不能摆脱构造函数,或者用=default
替换它吗?
另外,我不确定memcpy会比这些简单构造函数调用的循环展开和内联链快得多吗?
答案 2 :(得分:-2)
您可以根据需要来回记忆对象。结构的二进制表示和对齐要求是相同的。
如果您真的不相信它,可以创建static_asserts来检查大小和偏移量是否相同。