Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/142.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将具有自定义删除器的唯一\u ptr移动到共享\u ptr_C++_C++11_Shared Ptr_C++14_Unique Ptr - Fatal编程技术网

C++ 将具有自定义删除器的唯一\u ptr移动到共享\u ptr

C++ 将具有自定义删除器的唯一\u ptr移动到共享\u ptr,c++,c++11,shared-ptr,c++14,unique-ptr,C++,C++11,Shared Ptr,C++14,Unique Ptr,我有一个函数,它使用自定义删除器创建一个唯一的\u ptr并返回它: auto give_unique_ptr() { auto deleter = [](int* pi) { delete pi; }; int* i = new int{1234}; return std::unique_ptr<int, decltype(deleter)>(i, deleter); } 我要写什么来代替。。??。。要得到正确的类型 如果这是可能的

我有一个函数,它使用自定义删除器创建一个唯一的\u ptr并返回它:

auto give_unique_ptr() {
    auto deleter = [](int* pi) {
        delete pi;
    };
    int* i = new int{1234};
    return std::unique_ptr<int, decltype(deleter)>(i, deleter);
}
我要写什么来代替。。??。。要得到正确的类型

如果这是可能的,
shared_ptr
是否会表现良好,并在使用计数为零时调用在
give_unique_ptr()函数中创建的自定义删除程序?

auto uniquePtr=give_unique_ptr();
auto uniquePtr = give_unique_ptr();
auto sharedPtr = std::shared_ptr<decltype(uniquePtr)::element_type>(std::move(uniquePtr));
自动共享dptr=std::shared_ptr(std::move(uniquePtr));
是的,
shared\u ptr
将存储并在以后使用自定义删除程序。

如果您知道(或希望显式键入)对象的类型,则可以执行以下操作:

std::shared_ptr<int> sharedPtr(std::move(uniquePtr));
其中
make_shared_from
为:

template<typename T, typename D>
std::shared_ptr<T> make_shared_from(std::unique_ptr<T,D> && p)
{
   //D is deduced but it is of no use here!
   //We need only `T` here, the rest will be taken 
   //care by the constructor of shared_ptr
   return std::shared_ptr<T>(std::move(p));
};
模板
std::shared_ptr make_shared_from(std::unique_ptr&&p)
{
//D是推导出来的,但在这里没有用!
//我们这里只需要'T',其余的就可以了
//由共享ptr的构建者负责
返回std::shared_ptr(std::move(p));
};

希望这会有所帮助。

IMO,最好让
获取一个右值引用,使其外部可见正在移动from@RyanHaining或者甚至是一个值,在大多数情况下,这更符合C++11的习惯用法。@o11c我不能说我同意,除了引起额外的移动,还会有什么不同吗?@o11c
共享的ptr
构造函数采用
唯一的ptr&&
,因此很难将其称为更“惯用”的取值。自定义删除器可能会更大,以至于额外的移动可能不会像您认为的那样微不足道。经过。移动一个指针很简单,而移动一个
唯一的\u ptr
则不是。sink参数的
&&
是有意义的,并且是惯用的,即使您有一个sink-only类型。对于一个内联函数,所有这些寄存器/指针计数无论如何都无关紧要。@Ryan关于“我们不知道定制删除器的成本”的观点是很好的。我会选择
std::shared\u ptr share\u unique\u ptr(std::unique\u ptr&&ptr)
我自己作为名称/签名:返回共享ptr的事实应该是函数名的一部分。请记住
shared\u ptr
会擦除删除器。唯一的模板参数是当前视图中指向的类型。@o11c这是什么意思?我尝试了@Nawaz提出的解决方案,删除程序在
共享的ptr
被销毁后被调用。这意味着删除程序的类型与
共享的ptr
的类型无关。您甚至可以强制转换到(比如)一个
共享的\u ptr
,它仍然会调用原始的deleter。
auto sharedPtr = make_shared_from(std::move(uniquePtr));
template<typename T, typename D>
std::shared_ptr<T> make_shared_from(std::unique_ptr<T,D> && p)
{
   //D is deduced but it is of no use here!
   //We need only `T` here, the rest will be taken 
   //care by the constructor of shared_ptr
   return std::shared_ptr<T>(std::move(p));
};