gpt4 book ai didi

c++ - 我是否误解了这个默认参数 shared_ptr 的范围?

转载 作者:可可西里 更新时间:2023-11-01 18:27:50 34 4
gpt4 key购买 nike

看看这个:

#include <iostream>
#include <memory>

using Foo = int;
using FooPtr = std::shared_ptr<Foo>;

FooPtr makeFoo()
{
FooPtr f{
new Foo(),
[](Foo* ptr) {
delete ptr;

std::cerr << "!\n";
}
};

return f;
}

void bar(FooPtr p = {})
{
p = makeFoo();
}

int main()
{
bar();
}

// Expected output: '!'
// Failure case: no output (deleter not invoked?)

我希望 shared_ptr 删除器在 bar() 返回时被调用,在我使用 GCC 4.8.5 的 64 位 CentOS 7 系统上,它确实如此。

但是,在我的 32 位 CentOS 6 系统上,在 devtoolset-2 下使用 GCC 4.8.2(我认为gcc-linaro-arm-linux-gnueabihf-4.8-2013.10 下_linux,我的 Raspberry Pi 工具链),它没有。

查看代码,考虑到 C++11 在 4.8 中的实验性质,这对我来说就像一个编译器错误。但我也可能在某个地方陷入 UB 陷阱(或者只是普遍误解了这些东西应该如何工作)。

谁的错?我该如何解决?


致力于

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install --enable-gnu-indirect-function --with-tune=generic --with-arch_32=x86-64 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-16) (GCC)

失败

Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/rh/devtoolset-2/root/usr/libexec/gcc/i686-redhat-linux/4.8.2/lto-wrapper
Target: i686-redhat-linux
Configured with: ../configure --prefix=/opt/rh/devtoolset-2/root/usr --mandir=/opt/rh/devtoolset-2/root/usr/share/man --infodir=/opt/rh/devtoolset-2/root/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --enable-languages=c,c++,fortran,lto --enable-plugin --with-linker-hash-style=gnu --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.2-20140120/obj-i686-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.2-20140120/obj-i686-redhat-linux/cloog-install --with-mpc=/builddir/build/BUILD/gcc-4.8.2-20140120/obj-i686-redhat-linux/mpc-install --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
Thread model: posix
gcc version 4.8.2 20140120 (Red Hat 4.8.2-15) (GCC)

最佳答案

析构函数应该在 bar 返回时或在调用 bar 的完整表达式结束时调用。

如果我们查看 [expr.call]/4(C++17 草案),我们有

When a function is called, each parameter (11.3.5) shall be initialized (11.6, 15.8, 15.1) with its corresponding argument.[...]It is implementation-defined whether the lifetime of a parameter ends when the function in which it is defined returns or at the end of the enclosing full-expression.[...]

所以p应该在函数开始时被初始化为空的FooPtr,移动赋值给MakeFoo的返回值,最后在 bar 末尾或 barmain 中返回后销毁(依次调用删除器)。

关于c++ - 我是否误解了这个默认参数 shared_ptr 的范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49498090/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com