c++ - f() 按值返回对象的 "auto&& a= f();"中 a 的生命周期是多少?

标签 c++ lifetime rvalue-reference type-deduction forwarding-reference

#include <iostream>
#include <typeinfo>

class A {};

A f() { return A(); }

int main() {
    auto &&a = f();
    std::cout << typeid(f()).name() << std::endl;
    std::cout << typeid(a).name() << std::endl;
    std::cout << typeid(A{}).name() << std::endl;
    return 0;
}

输出

1A
1A
1A

问题是,

  1. 这里1A是什么意思? (Linux 机器上的 GCC)
  2. auto && 应该是转发引用,在这种情况下,由于 f() 按值返回 A 对象, a 应该被推导为右值引用,对吗?
  3. 如果 a 确实是右值引用,并且由于(临时)右值的生命周期只能通过 const 左值引用来延长,因此 a 应该在之后立即超出范围这句话正确吗?

编辑:正如许多人指出的那样,修复了最后一个 cout 语句中最令人烦恼的问题。

总结优秀答案,供后代使用:

  1. 1A 是类型 A 的内部表示,由 Guillaume Racicot 编写。 F1AvE 表示 typeid(A()) 中的函数样式转换,产生纯右值,作者:Ted Lyngmo。
  2. 事实证明 typeid() 不是检查引用的工具,因为它给出了引用的结束类型。 Ted Lyngmo 给出了正确的方法,是的,它是一个 r 值引用。
static_assert(std::is_rvalue_reference_v<decltype(a)>); // like this, ...
static_assert(std::is_same_v<decltype(a), A&&>);        // or like this
  • 理查德·克里滕 (Richard Critten) 提供的链接显示 "The lifetime of a temporary object may be extended by binding to a const lvalue reference or to an rvalue reference (since C++11)..." .
  • 最佳答案

    what does 1A mean here? (GCC on a linux box)

    表示名称长度为1后跟字母。关于如何修改类型有很多规则,但它对其命名空间、模板参数值和其他内容进行编码。

    auto && should be a forwarding reference, and in this case since f() returns an A object by value, a should be deduced to rvalue reference, correct?

    typeid 运算符会丢弃所有顶级 cv 和 ref 限定符。

    此外,它还可以查看引用并返回引用类型的类型信息。

    来自typeid operator页面:

    If type is a reference type, the result refers to a std::type_info object representing the referenced type.

    但是,推导的类型是 A,因此您声明的是 A&&。但即使 a 是右值引用,表达式 a 也是左值。

    If a is indeed rvalue reference, and since a (temporary) rvalue's lifetime could only be extended by a const lvalue ref, a should go out of scope right after this line, is that correct?

    根据生命周期扩展规则,生命周期在范围结束时结束。


    现在来了解为什么 typeid 不同。

    这与右值或转发引用无关。这是最令人烦恼的解析问题。 A() 是一个返回 A 且没有参数的函数。

    使用 {} 进行初始化,您将看到问题消失:

    #include <iostream>
    #include <typeinfo>
    
    class A {};
    
    A f() { return A(); }
    
    int main() {
        auto &&a = f();
        std::cout << typeid(f()).name() << std::endl; // 1A
        std::cout << typeid(a).name() << std::endl;   // 1A
        std::cout << typeid(A{}).name() << std::endl; // 1A
        return 0;
    }
    

    关于c++ - f() 按值返回对象的 "auto&& a= f();"中 a 的生命周期是多少?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67729204/

    相关文章:

    Android SDL2 在锁定屏幕上恢复

    c++ - C++ 中类静态变量的生命周期是多少?

    rust - lazy_static 可变变量的生命周期问题

    c++ - move 自定义容器的构造函数?

    c++ - 防止带有尾随返回类型的悬空右值引用

    c++ - std::move 不适用于 RValue 引用函数

    c++ - %g 精度问题

    c++ - 使用 FFmpeg 将原始 RGB32 文件转换为 JPEG 或 PNG

    c++ - Python初始化段错误

    iterator - 实现 Iterator 时的生命周期问题