假設我有一些具有初始名稱的物件,例如quantities_of_widgets.
std::vector<int> quantities_of_widgets = GetQuantities();
然后我quantities_of_widgets就地執行操作。該向量quantities_of_widgets不再表示“稱為小部件的某些數量的向量”。
PerformOperationInPlace(quantities_of_widgets);
在此操作之后,更合適的變數名稱將是weights_of_widgets. 這肯定會使代碼更具可讀性。
我可以通過移動quantities_of_widgets到新的 vector來“更改”名稱weights_of_widgets。這是一個可怕的想法。移動不是免費的,它會干擾記憶體連續性等。
std::vector<int> weights_of_widgets = std::move(quantities_of_widgets);
我還可以在注釋中記錄變數的含義。我可能會寫
std::vector<int> widgets = GetQuantities(); // widgets represents quantities
PerformOperationInPlace(widgets); // widgets represents weights
UseWeights(widgets);
但是,注釋的永久性和可讀性較差。在多行代碼中跟蹤變數的含義變得更加困難。如果widgets在大型運算式中間向下使用 20 行,我將無法記錄該變數的含義。
SomeBigFunction(Func1(widgets, some_other_object_1), some_other_object_2);
我可以嘗試別名,但我想讓舊名稱無效以幫助維護。有沒有辦法在沒有運行時成本的情況下更改變數的名稱?
uj5u.com熱心網友回復:
除了最極端的情況外,擔心如此小的開銷幾乎肯定不值得付出努力。但是,為了完整起見:
使用非平凡解構式獲得真正無開銷的型別重命名的唯一方法是通過復制省略。
在這種情況下,您可以通過立即評估的 lambda 和 NRVO 來使用它。
#include <vector>
std::vector<int> GetQuantities(int v);
void PerformOperationInPlace(std::vector<int>&);
void UseWeights(const std::vector<int>&);
template<typename T>
T rename(T&& rhs) {
return rhs;
}
void foo(int x) {
std::vector<int> quantities_of_widgets = GetQuantities(x);
PerformOperationInPlace(quantities_of_widgets);
UseWeights(quantities_of_widgets);
}
void bar(int x) {
std::vector<int> weights_of_widgets = [&]{
std::vector<int> quantities_of_widgets = GetQuantities(x);
PerformOperationInPlace(quantities_of_widgets);
return quantities_of_widgets;
}();
UseWeights(weights_of_widgets);
}
foo()并bar()編譯成完全相同的最終組裝:(參見Godbolt)
唯一的限制是要重命名的變數必須在 lambda 中宣告。除此之外,通過參考隱式捕獲使 lambda 有效地與作用域相同。
uj5u.com熱心網友回復:
最好自己記錄代碼。評論有降低的趨勢。所以我會這樣做:
// name of this function terrible, it should be more like
// ExtractWeightsOfWidgetsFrom or something similar
std::vector<int> OperationInPlace(std::vector<int> data) {
// note argument is a copy!
....
return data;
}
void someCode() {
auto quantities_of_widgets = GetQuantities();
...
auto weights_of_widgets = PerformOperationInPlace(std::move(quantities_of_widgets));
// here `quantities_of_widgets` is empty since contents has been moved
// many tools will report an error if you use this value after that point
....
}
或者更好的是,我只想提取更多功能:
void someCode() {
auto quantities_of_widgets = GetQuantities();
...
ProcesWeightsOfWidgets(
PerformOperationInPlace(std::move(quantities_of_widgets));
// in this version someCode ends here
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/358496.html
