繁体   English   中英

从返回值的引用移至std :: mo时的自动安全性

[英]Safety of auto when std::move ing from a returned reference of a value

我需要放心,无论何时使用以下方法来分配或列表初始化auto键入的命名变量:

  • 一个std::move ()ed返回对变量的引用
  • B返回对变量的引用

在表达式之后,原点超出范围的地方是A安全/ B不安全。 示例代码:

#include <iostream>
#include <string>
#include <deque>
#include <utility>

int main() {
    std::deque<std::string> container {"foo"};
    auto elementB = container.front(); //B I assume this is unsafe
    auto elementA = std::move(container.front());//A I assume this is safe
    container.pop_front();

    std::cout << "A: " << elementA << " B: " << elementB  << "\n";
}

据我所知,表达式B生成赋值的左值,因此elementB的类型是左值引用,也称为std::string& ,因此这是不安全的。

执行代码时,“ A:foo B:”的输出也表明了这一点。 https://ideone.com/wKKbdK )更新:对不起,我忘了我移动了它,所以我更改了顺序,现在输出为例外,抱歉。

但是,我不确定的最麻烦的事情是表达式A:在std::move之后,我假设我得到了既是rvalue又是glvalue的xvalue,因此我不确定该类型的标准化行为(如果有)推导elementA

因为从lvalues我几乎可以确定它的UB,而lvalues是glvalues,xvalues是它们的一部分,那么elementA的类型将是std::string&& ,这是不安全的,对吗? (除非const && AFAIK例外)

总结一下: elementA的使用是否是安全的标准化行为,其类型将是什么?

使用elementA是否安全,规范?

是。

...它的类型是什么?

它的类型将是std::string auto类型推导的工作方式类似于模板类型推导,其中包括删除参考的“参考性”。 std::move(container.front())返回xvalue的事实在这里并没有太大改变。 它是一个“过期”值,您可以(a)移动构造一个新对象(如您当前所做的那样)(b)将其绑定到const限定的引用,或者(c)将其绑定到一个rvalue-reference。 在这里,(b)和(c)都可以工作,但意义不大,因为它们掩盖了什么都没有移走的事实(感谢@MM在这里纠正了我)。 例:

auto elementA = std::move(container.front());
// Error, can't bind to non-const reference:
// auto& doesntWork = std::move(container.front());
auto&& thisWorks = std::move(container.front());
const auto& thisWorksToo = std::move(container.front());

请注意,正如@MM在注释中指出的那样,一旦container.pop_front();后面的两个引用将悬而未决container.pop_front(); 遇到。

还要注意,将elementBstd::string并不能帮助您取消引用移出的对象(由container.front()返回),这一点应避免。

您的代码很好,因为elementAelementBelementB 导出string ,而不是引用( string&string&& )。

给定auto elementA ,初始化器的引用部分将被忽略。 如果要引用elementAelementB ,则必须明确指定,例如auto&& elementAauto& elementB

您可能将值类别与类型混淆; 他们是独立的。 初始化程序的值类别,即它是一个左值或右值,不会影响类型推导 在您的代码中,给定auto elementAelementA将为std::string类型,给定auto& elementA ,其类型将为std::string& ,给定auto&& elementA ,其类型将为std::string&&

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM