c++ - 在 C++ 中恢复临时赋值

标签 c++ variable-assignment

在访问者上下文中,我需要在访问 child 之前临时设置一个变量,然后再恢复该变量。我正在使用以下代码,但我确信有一种更优雅、更正确的方法可以做到这一点:

template <typename TYPE> class TemporaryAssignment {
protected:
    TYPE& mVariable;
    TYPE mOriginalValue;
public:
    TemporaryAssignment(TYPE& inVariable, TYPE inValue) 
        : mVariable(inVariable), mOriginalValue(inVariable) {
        mVariable = inValue;
    }
    ~TemporaryAssignment(void) {
        mVariable = mOriginalValue;
    }
};

这使我可以编写如下内容:

{
    ...
    TemporaryAssignment<string> t(myVariable, myTemporaryValue);
    visitChildren();
    ...
}
// previous value of myVariable is restored

当临时赋值对象超出范围时,变量将恢复到它以前的值。执行此操作的更好方法是什么?

最佳答案

除了析构函数可以抛出外,在我看来还不错,这很糟糕。 swap 与原始值而不是赋值(编辑:这涉及 std::string,但请参阅注释以了解可能存在的问题,这些类的用户友好性低于 字符串)。

如果您从这部分代码中退一步,也许您可​​以找到一种根本不需要设置临时值的方法。对象中共享可变状态的坏处与可变全局变量坏处的原因相同,但程度较轻,因为它只会弄乱你的类,而不是弄乱你的整个程序。

例如,也许您可​​以复制整个对象,为变量设置一个新值并访问拷贝而不是访问自己。显然,这不一定可行或有效,您必须根据具体情况寻找替代方案。也许就子项而言,拷贝可能很浅(即引用相同的子对象),这可能足以使其便宜。

关于用法,您可以像这样推断类型(未经测试的代码):

template <typename T, typename ARG>
TemporaryAssignment<T> temp_value(T &var, ARG &&newvalue) {
    return TemporaryAssignment(var, std::forward<ARG>(newValue));
}

用法:

auto t = temp_value(myVariable, myTemporaryValue);

然后您需要一个用于 TemporaryAssignment 的移动构造函数:

template <typename TYPE> class TemporaryAssignment {
    // change data member
    TYPE *mVariable;
    TYPE mOriginalValue;
public:
    TemporaryAssignment(TYPE &inVariable, TYPE inValue) 
    : mVariable(&inVariable), mOriginalValue(std::move(inVariable)) {
        *mVariable = std::move(inValue);
    }
    TemporaryAssignment(TemporaryAssignment &&rhs) {
        mOriginalValue = std::move(rhs.mOriginalValue);
        mVariable = rhs.mVariable;
        rhs.mVariable = 0;
    }
    ~TypeAssignment() {
        using std::swap;
        if (mVariable) {
            swap(*mVariable, mOriginalValue);
        }
    }
    // can't remember whether this is needed
    TemporaryAssignment(const TemporaryAssignment &) = delete;
    TemporaryAssignment &operator=(const TemporaryAssignment &) = delete;
    TemporaryAssignment &operator=(TemporaryAssignment &&) = delete;
};

我想过为 TemporaryAssignment 指定 operator= 以使用法看起来像一个赋值,但我没有想出任何好办法。

auto t = (temporary(myVariable) = myTemporaryValue);

是合理的,但您可能不希望 TemporaryAssignment 定义 operator=,因为以下含义:

t = otherTemporaryValue;

不一定清楚,可能不应该被允许。也许从 temporary 返回第二个类,它从它的 operator= 返回 TemporaryAssignment

关于c++ - 在 C++ 中恢复临时赋值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13383683/

相关文章:

c++ - 冒泡排序阻止我的程序执行

c++ - sleep 线程和构造函数中的线程初始化

c++ - boost asio 和 endian

c++ - 给定一个随机数列表 [0, 1] : can I use the standard library to convert to a specific distribution?

java - 为什么不能将两个字节加一个整数并可以将两个最后字节加一个字节?

c++ - 从构造函数的初始化列表中捕获异常

c++ - 指向二维数组的特定行

java - java中a + = 10和a = a + 10之间的区别?

c - 这个 C 结构赋值是什么意思?

ruby - 在并行赋值中删除值