我想更好地瞭解如何在C++中移動工作。編譯器如何知道何時移動以及何時不移動?編譯器何時在C++中移動/複製?
#include <iostream>
template <typename T>
struct Container {
T value;
Container (T value): value(value) {}
Container (const Container & i): value(i.value) {
std::cout << "copying" << std::endl;
}
Container (Container && i): value(std::move(i.value)) {
std::cout << "moving" << std::endl;
}
};
void increment (Container<int> n) {
std::cout << "incremented to " << ++n.value << std::endl;
}
int main() {
Container<int> n (5);
increment(std::move(n));
std::cout << n.value << std::endl;
}
這個例子打印
moving
incremented to 6
5
所以我預計int
已被轉移,但當時我不應該能夠仍然使用它之後(並獲得原始值)。
好吧,所以也許int
被複制,因爲value(std::move(i.value))
在移動構造函數中複製它。但我仍然不明白爲什麼Container<int> n
仍然在它被移動後仍然存在。
請注意,通過優化,由於副本構造函數(以及我相信也是移動構造函數)中的副作用可以忽略,所以可能永遠不會顯示您的輸出語句。 – rubenvb
「所以我期望'int'已經被移動了,但之後我不能繼續使用它」爲什麼不呢?編譯器是否應該用垃圾數據和每一個獲得'std :: move'd的原始類型來排除錯誤,只是爲了與錯誤的移動語義定義相對應?這將代表反向優化。遷移的存在是爲了實現資源的最佳轉移。根據定義,原始類型沒有任何資源。 –
@rubenvb這是真的,但不是在_all_情況下。例如,對於初始化和函數返回,允許複製elision。但是,我不相信在OP的例子中它是被允許的。 – davmac