use*_*453 8 c++ move-semantics c++11
这个:
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;
}
Run Code Online (Sandbox Code Playgroud)
有没有办法告诉编译器给我一个错误(或警告)如果我不小心使用了可变我提出以后呢?我觉得这很方便.很多时候我发现自己在其他地方移动变量,但后来我手动必须非常小心,以后我不再使用它们.现在这还没有引起任何问题,但是谁知道这一点......更好的是安全!
也许有一些预处理器技巧(或相当广泛可用的编译器扩展)存在来做这些事情?
更现实的例子:
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;
}
Run Code Online (Sandbox Code Playgroud)
And*_*owl 10
如果我在移动变量后意外使用变量,是否无法告诉编译器给我一个错误(或警告)?
答案是"不,没有办法"(据我所知,至少目前没有可用的编译器提供这样的选项,并且有充分的理由 - 见下文).
即使这是可能的,为什么你会期望在这种情况下发出警告,甚至更糟糕的错误呢?首先,从整数移动与复制它没有任何不同.
其次,对于大多数类型,分配该类型的移动对象是完全合法的操作; 对于基本类型来说int,这总是如此,并且它确实是正确的std::vector,尽管它可能不适用于其他类型.
通常,分配移动对象是否合法取决于该类型的移动操作的特定后置条件以及赋值运算符的前提条件(标准库类型的赋值运算符没有前提条件)左手边的论点).这是编译器在一般情况下无法检查的内容.
因此,如果你是:
std::vector)的对象移动,然后;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()?
Run Code Online (Sandbox Code Playgroud)
此外,不要忘记C++的哲学是给你力量和(最常见的)设计指导,但如果你真的想要这样做,"让你射击你的脚".
这里是危险的,甚至是毫无意义的事情,你可以在C做++(将你的编译器给你一个警告或错误,如果你试图delete同一指针两次?),但语言本身不会阻止你做他们,假设你真的,真的知道你在做什么.
//do some things, but I gotta be careful I don't do anything to vec
Run Code Online (Sandbox Code Playgroud)
澄清:你需要小心,你不做任何事情vec需要一个先决条件.你可以做任何事情vec,它不要求任何先决条件.例如,您可以指定vec新值.你可以打电话vec.clear().你可以打电话vec.size().但是不要调用vec.pop_back()因为该成员函数有前提条件.