假设我有一些带有初始名称的对象,例如 quantities_of_widgets
。
std::vector<int> quantities_of_widgets = GetQuantities();
然后我就地对 quantities_of_widgets
执行操作。 vector quantities_of_widgets
不再表示“称为小部件的某些数量的 vector ”。
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);
我可以尝试别名,但我想让旧名称无效以帮助维护。有没有一种方法可以更改变量的名称而不需要运行时成本?
最佳答案
除了最极端的情况外,几乎肯定不值得担心如此小的开销。但是,为了完整起见:
使用非平凡析构函数获得真正无开销的类型重命名的唯一方法是通过复制省略。
在这种情况下,您可以通过立即评估的 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 实际上与作用域相同。
关于c++ - 在函数中间更改变量名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69945441/