带有不同括号的 C++ Lifetieme 扩展 [Duplicate]

c++ lifetieme extension with different parentheses [duplicate]

提问人:user3882729 提问时间:4/24/2023 最后编辑:songyuanyaouser3882729 更新时间:4/24/2023 访问量:502

问:

我正在尝试了解 C++ 中的生命周期延长保证。有人可以解释为什么在下面使用不同类型的括号会在调用临时对象析构函数时产生不同的结果吗?

#include <iostream>
struct X  {
    X() { 
        std::cout << __PRETTY_FUNCTION__ <<"\n";
    }
    ~X() {
        std::cout << __PRETTY_FUNCTION__ <<"\n";
    }
};

struct Y {
    X &&y;
};
int main() { 
    Y y1(X{});    
    std::cout << "Here1\n";
    Y y2{X{}};
    std::cout << "Here2\n";
}

输出

X::X()
X::~X()
Here1
X::X()
Here2
X::~X()
C++ 生存期 临时对象

评论


答:

18赞 songyuanyao 4/24/2023 #1

C++20 开始:

此生存期规则存在以下例外情况:

  • ...

  • 临时绑定到 引用元素中的引用 使用直接初始化语法(括号)初始化的聚合 一直存在,直到包含 initializer,而不是列表初始化语法 {braces}。

    struct A
    {
        int&& r;
    };
    
    A a1{7}; // OK, lifetime is extended
    A a2(7); // well-formed, but dangling reference
    

这意味着 的 temporary 的生存期将延长为 (及其成员);而对于它不会,临时将在完全表达后立即销毁。Y y2{X{}};y2Y y1(X{});

评论

13赞 Silvio Mayolo 4/24/2023
我做 C++ 程序员已经快 15 年了,我无法完全解释为什么有这么多具有极其微妙差异的初始化语法。甚至。
3赞 Peter 4/24/2023
@SilvioMayolo 即使是与C++打交道超过 15 年的人也很难理解其中的差异。原因很大程度上是历史性的,因为该语言在保持向后兼容性的同时不断发展。一些语法/语义保留在 C 中,其他一些来自早期 C++ 标准(以及以前的标准草案)。C++ 引入了语法/语义来帮助解决挫折(例如最令人烦恼的解析),并更好地支持新的语言功能(例如右值引用等)。C++17 和后来的进一步调整...
0赞 digito_evo 4/24/2023
好吧,这是为什么支撑初始化应该比其他初始化更受欢迎的另一个原因。