c++ - 在参数中移出的智能指针上调用方法是否安全?

标签 c++ c++11 language-lawyer shared-ptr move-semantics

这段代码安全吗?如果方法接受值或右值引用,答案会改变吗?是否会更改为 unique_ptr

struct foo
{
    void bar(std::shared_ptr<foo> p) // or std::shared_ptr<foo>&&
    {
        // the object will be deleted at the end of the call unless p is
        // moved/copied elsewhere at some point
    }
};

int main()
{
    auto p = std::make_shared<foo>();
    p->bar(std::move(p));
    return 0;
}

主要问题专门针对这一行:

p->bar(std::move(p));

这是否保证始终捕获 p.operator->() 的当前值在构建论证之前?或者从 p 搬出后会发生这种情况吗? ?

(注意:我相信这对于 std::shared_ptr<foo>&& 参数是安全的,因为实际的 move 构造直到在方法体内才会发生(如果有的话)。但是当按值传递时,参数构造可以[其中包括 move 构造]发生在调用 p.operator->() 之前,还是总是严格在调用之后?)

最佳答案

如果您使用std::shared_ptr<foo>&&作为参数类型(或任何引用类型),那么就没有问题,因为std::move call 实际上不会以任何方式修改对象。是否先执行并不重要。

在 C++17 之前,按值变体并不安全。没有排序规则可以保证在函数参数初始化之前对命名函数的表达式进行求值。因此函数参数的 move 构造可能发生在p->bar之前。已评估。

自 C++17 起,命名函数的后缀表达式的值计算和所有副作用都在调用参数中的所有表达式的值计算和副作用之前排序,这意味着函数的构造函数参数在评估p->bar之后排序。请参阅[expr.call]/5 。 因此潜在的问题operator->调用p首先发生在 move 构造之前,使代码安全。

如果替换 std::shared_ptr,同样的语句成立。与 std::unique_ptr .

关于c++ - 在参数中移出的智能指针上调用方法是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60700769/

相关文章:

c++ - C++中的 "type of expression"是什么?

c++ - OpenCV 和虚拟 C++ : save Frame data from Camera and then save to Jpg

c++ - 为什么 C++ 运算符重载需要 "having at least one parameter of class type"?

c++ - 没有兼容的方法来转换相同大小的有符号/无符号

c++ - std::vector::iterator 是否可以合法地成为指针

c++ - 我认为 §7.3.1.2/1 中的示例不正确

c++ - 如何创建多个模板对象的数组

c++ - 如何在类初始值设定项中设置 union ?

c++ - 即时生成数据供媒体基金会使用

c++ - 默认成员值最佳实践