c++ 一个临时对象可以被解引用并在另一个函数中进一步传递吗?

qmb5sa22  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(137)

基本上我有两个相关的问题。让我们假设,有一个函数来创建一个共享指针,例如:std::shared_ptr<int> create_ptr(int val)
有一个函数通过引用接受,例如:void print(int& val)
我想创建一个共享指针,并将其直接传递给函数,如下所示:print(*create_ptr(123))
运算符 *()应该返回一个引用,但它将是对临时对象的引用。
你能告诉我,这样做是否仍然安全,并且根据C++规则是否完全正常?
我不确定,但我假设这是正常的,因为对象是分配的,直到函数完成才被删除。所以共享指针是临时的,但对象是真正分配的。
如果是这样的话,那么它可以解释为什么下面的代码编译得很好:

std::shared_ptr<int> create_ptr(int val)
{
    return std::make_shared<int>(val);
}

void print(int& val)
{
    std::cout << "*** Print value: " << val << '\n';
}

int main()
{
    print(*create_ptr(123)); // Why does it work?
}

当我第一次写代码的时候,我预料到了一个编译错误,因为传递的对象是临时的,现在我仍然很困惑,为什么这应该工作?你怎么解释
谢谢你!
代码已经用GCC-10进行了测试,编译得很好,工作正常。

uurv41yg

uurv41yg1#

ptr的生存期将持续到整个表达式的求值,其中包括对print的调用。
关于specs
所有临时对象都被销毁,这是计算完整表达式的最后一步,该表达式(词法上)包含了它们被创建的点,如果创建了多个临时对象,则它们被销毁的顺序与创建顺序相反。即使该计算以引发异常而结束,也是如此。

fwzugrvs

fwzugrvs2#

我预计会出现编译错误,因为传递的对象是临时的,现在我仍然很困惑,为什么这样做会起作用?
它之所以编译是因为共享指针类的间接操作符重载不是左值ref限定的,所以在右值(如临时值)上调用它是有效的。
我假设,这是正常的,因为对象是分配的,而不是删除,直到函数完成。
你的假设是正确的。它没有解释为什么程序编译,但它解释了为什么行为定义良好。

相关问题