C++ 为什么要选择<;T&&燃气轮机;重新绑定任务?

C++ 为什么要选择<;T&&燃气轮机;重新绑定任务?,c++,reference,optional,c++17,C++,Reference,Optional,C++17,关于optional和variant应该如何处理引用类型,特别是在赋值方面,人们一直在争论。我想更好地理解围绕这个问题的辩论 optional<T&> opt; opt = i; opt = j; // should this rebind or do i=j? opt=j应该重新绑定基础引用的参数是什么 我不知道你要找的“论点”是什么。但你刚刚提出了一个“论点”: 可选选项; opt=i; opt=j; 现在,假设第二行和第三行彼此远离。如果您正在阅读代码,您希望opt

关于
optional
variant
应该如何处理引用类型,特别是在赋值方面,人们一直在争论。我想更好地理解围绕这个问题的辩论

optional<T&> opt;
opt = i;
opt = j; // should this rebind or do i=j?
opt=j应该重新绑定基础引用的参数是什么

我不知道你要找的“论点”是什么。但你刚刚提出了一个“论点”:

可选选项;
opt=i;
opt=j;
现在,假设第二行和第三行彼此远离。如果您正在阅读代码,您希望
opt=j
做什么?或者更重要的是,为什么您希望它的行为不同于
opt=i

纯粹基于包装器的当前状态,包装器类型的行为会有如此大的差异,这是非常令人惊讶的

此外,我们已经有了一种沟通方式,即您希望更改
可选
中的值。即:
*opt=j
。这对于
可选
可选
一样有效


optional
的工作方式非常简单:它是一种包装类型。与任何当前存在的包装器类型一样,对它们的操作影响包装器,而不是被包装的东西。为了影响被包装的对象,您可以显式地使用
*
->
或其他一些接口函数。

在您的示例中,如果
opt=i
绑定一个引用,然后
opt=j
通过引用赋值,这不是很奇怪吗?你很难使用赋值绑定普通引用。特别是当
opt
作为函数参数输入时,这取决于运行时
opt=i分配或绑定我们已经用
auto ref=std::ref(i)重新绑定了
std::reference\u包装器
;ref=j(由于非显式构造函数)。因此,对于一致性,重新绑定似乎更符合逻辑。我发现你的最后一段最引人注目——包装器上的操作会影响包装器。但其余的都是有意义的。实际上,这就是在分配给参与的可选项时不使用T型运算符=的论点,即使不涉及引用。@ГПццццццццццццц?在这种情况下,
operator=
应该做什么是毫无疑问的。它可能只意味着一件事:有两种完全不同的操作:“赋值”(在引用的情况下会重新绑定引用)和在optional的操作符=”中使用的“重置包装器”。如果参数是对optional的操作应该影响optional的状态,而不是其值的状态,那么operator=唯一可能的意思是“reset_wrapper”-如果存在当前值,则完全销毁当前值,然后包装新值。@ГППППППиицццццццццццц,“我希望可选项保留此值。如果可选项不包含任何对象,则需要将构造复制/移动到其中。如果可选对象已包含对象,则您希望将赋值复制/移动到已包含的对象中,以便该对象现在具有新值。无需销毁当前对象并创建新对象。“销毁和复制构造”和“复制分配”之间没有有用的区别。当然除了性能,这就是为什么我们要做后者。
template <class T>
struct optional<T&> {
    T* ptr = nullptr;

    optional& operator=(T& rhs) {
        ptr = &rhs;
        return *this;
    }
};
optional<T&> opt;
opt = i;
opt = j;