簡體   English   中英

在函數中間更改變量名

[英]Changing variable names in the middle of a function

假設我有一些具有初始名稱的對象,例如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到一個新的載體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);

但是,注釋的永久性和可讀性較差。 在多行代碼中跟蹤變量的含義變得更加困難。 如果在大表達式中間向下 20 行使用widgets ,我將無法記錄此時變量的含義。

SomeBigFunction(Func1(widgets, some_other_object_1), some_other_object_2);

我可以嘗試別名,但我想讓舊名稱無效以幫助維護。 有沒有辦法在沒有運行時成本的情況下更改變量的名稱?

除了最極端的情況外,擔心如此小的開銷幾乎肯定不值得付出努力。 但是,為了完整起見:

使用非平凡析構函數獲得真正無開銷的類型重命名的唯一方法是通過復制省略。

在這種情況下,您可以通過立即評估的 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 有效地與作用域相同。

最好自己記錄代碼。 評論有降低的趨勢。 所以我會這樣做:

// 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
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM