提问人:metamorphosis 提问时间:4/21/2023 更新时间:4/21/2023 访问量:107
有没有办法防止 C++ 编译器将临时右值的副本优化为移动操作?
Is there a way of preventing a C++ compiler from optimizing a copy of a temporary rvalue into a move operation?
问:
例如:
std::vector<int> i;
i = std::vector{5, 4, 3, 2, 1}
在上述情况下,编译器通常会将第二行优化为移动操作而不是复制操作,尽管缺少 std::move() 外壳。这通常没问题,但在某些情况下可能会导致问题,例如,如果使用特定分配器声明,则目标分配器所发生情况的语义非常不同,具体取决于操作是复制还是移动(如果矢量实现符合标准)。
让我们忽略上面是坏代码,即。它应该是一条线,没有不必要的辅助向量构造,并专注于另一个问题。i
我们可以假设其他用例,在这些用例中,移动旨在对容器元数据执行略微不同的操作。假设我们有一个结构:
struct t
{
int data;
int usage;
// Methods and constructors etc go here
};
该变量告诉我们给定方法访问了多少次。从语义上讲,复制操作可能只是将变量从一个结构实例复制到另一个结构实例。移动操作也希望替换变量,因为它有效地将一个结构实例的整个状态移动到另一个结构实例。忽略你是否认为这不太可能,这只是一个假设的例子,用于说明目的。usage
data
data
usage
现在,如果有人写了一些糟糕的代码,例如:
t a;
// Some accesses of a's data member occur here via a member function.
t b = 4;
a = b;
// b is not used after this point.
编译器可以将 b 优化为临时操作,并优化为移动操作。如前所述,这可能会导致问题。a = b
所以。
有没有办法 - 从结构的编写者方面 - 编写方法,以便复制赋值和移动赋值都是可能的,但 C++ 编译器无法将复制操作优化为移动操作 - 即使使用了临时右值?我知道代码的作者可以使用 来防止这种情况,但我对这种特殊情况下的万无一失代码感兴趣。operator =
t
谢谢-
答: 暂无答案
评论
a = b
优化为移动操作。如前所述,这可能会导致问题。不,它可能不是。 是一个左值。这里不允许进行此类优化。b
-std=c++98 -fno-elide-constructors -pedantic
std::move
std::move
i = std::vector{5, 4, 3, 2, 1}
std::move
std::forward