我发现了一些类似于:
#include <utility>
#include <cstdlib>
struct Core
{
void* mData{};
size_t mCount{};
};
template <typename T>
struct Actual: protected Core
{
Actual() = default;
Actual(Actual<T> const& other) = delete;
Actual<T>& operator=(Actual<T> const& other) = delete;
Actual(Actual<T>&& other):
Core{ other.mData, other.mCount }
{
other.mData = nullptr;
other.mCount = 0;
}
Actual<T>& operator=(Actual<T>&& other)
{
Actual<T> tmp(std::move(other));
std::swap(mData, tmp.mData); // with -O2 -Wall -Wextra -Werror: "error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]"
mCount = tmp.mCount; // ditto
return *this;
}
~Actual() { /* delete[] mData as array of T, if it was created */ }
// rest of the API incl. allocating that array of T into mData, not relevant
};
int main() {
Actual<int> a;
Actual<int> b;
b = std::move(a);
}在请求优化之前,这是很好的编译(-O2和更高版本)。
问题很简单,为什么编译器(GCC 9.3.0)认为这是类型双关/违反严格的混叠规则,我能做些什么来解决这个问题?
发布于 2021-07-10 09:54:20
看上去像GCC的虫子。GCC 9.4及更高版本不能诊断这一点。
如果您这样重写operator=,它就不再抱怨了,这个表单也更短了。
Actual<T>& operator=(Actual<T> other)
{
std::swap(mData, other.mData);
std::swap(mCount, other.mCount); // I like this more than `mCount = tmp.mCount;`.
return *this;
}要使其工作,您必须删除Actual<T>& operator=(Actual<T> const& other) = delete;,还不如删除Actual(Actual<T> const& other) = delete;。
您还应该将noexcept添加到move构造函数和这个赋值操作符中,以免标准容器(当调整大小时)决定复制类的实例而不是移动它们。
https://stackoverflow.com/questions/68326497
复制相似问题