gpt4 book ai didi

c++ - 使用已被 std::move 到别处的变量时出现错误,或至少出现警告

转载 作者:可可西里 更新时间:2023-11-01 17:26:06 25 4
gpt4 key购买 nike

这个:

void foo(int &&r) {
std::cout << r << std::endl;
}

int main() {
int i = 2;
foo(std::move(i));
i = 3; //no warning. any way to get some warnings here?
return 0;
}

如果我在 move 变量后不小心使用了它,是否没有办法告诉编译器给我一个错误(或警告)?我认为这会很方便。很多时候我发现自己像那样将变量 move 到其他地方,但后来我手动必须非常小心,以免以后不使用它们。现在这还没有造成任何问题,但谁知道呢……最好注意安全!

也许存在一些预处理器技巧(或相当广泛可用的编译器扩展)来执行此操作?


更现实的例子:

struct HugeStorage {
std::vector<double> m_vec;
HugeStorage(std::vector<double> vec) : m_vec(std::move(vec)) { }
};

struct SmallStorage {
std::vector<double> m_vec;
SmallStorage(std::vector<double> vec) : m_vec(std::move(vec)) { }
};

std::vector<double> vec_from_data_source() {
return std::vector<double>(); //only example!!
}

int main() {
std::vector<double> vec = vec_from_data_source();
if (vec.size() > 10000)
{
HugeStorage storage(std::move(vec));
//do some things, but I gotta be careful I don't do anything to vec
}
else
{
SmallStorage storage(std::move(vec));
//do some things, but I gotta be careful I don't do anything to vec
}
return 0;
}

最佳答案

Is there no way to tell the compiler to give me an error (or warning) if I accidentally use the variable after I have moved it?

答案是“不,没有办法”(至少据我所知,目前没有可用的编译器提供这样的选项,并且有充分的理由 - 见下文)。

即使这完全有可能,您为什么期望在这种情况下给出警告,甚至更糟的是错误?首先,从整数 move 与复制它没有任何不同。

其次,对于大多数类型,分配该类型的移出对象是完全合法的操作;对于 int 这样的基本类型总是如此,对于 std::vector 也是如此,尽管对于其他类型可能并非如此。

一般来说,分配一个移出的对象是否合法取决于该类型的 move 操作的特定后置条件和赋值运算符的前提条件(标准库类型的赋值运算符有左侧参数没有前提条件)。这是编译器在一般情况下无法检查的内容。

因此,如果您要:

  1. 从 move 赋值或 move 构造函数将移出对象置于未指定状态的对象中 move (std::vector 就是这种情况),然后;
  2. 在该对象的状态上调用具有先决条件的任何函数(不是分配给 std::vector 的情况);

那肯定不好。另一方面,编译器没有办法对您的程序执行语义分析并确定是否属于这种情况:

A x, y;
...
if (complicatedCondition())
{
y = move(x);
}

foo(x); // Did I move from x? And if so, is it safe to call foo()?

此外,不要忘记 C++ 的理念是为您提供强大的功能和(最常见的)设计指南,但如果您真的想这样做,“让您动弹不得”。

您可以在 C++ 中执行 危险甚至毫无意义的事情(如果您尝试删除相同的内容,您的编译器是否会给您警告或错误指针两次?),但语言本身不会阻止您这样做,前提是您真的非常知道自己在做什么。

关于c++ - 使用已被 std::move 到别处的变量时出现错误,或至少出现警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15075311/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com