Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++ 将原始指针传递给接受unique_ptr作为参数的函数_C++_Templates_Smart Pointers - Fatal编程技术网

C++ 将原始指针传递给接受unique_ptr作为参数的函数

C++ 将原始指针传递给接受unique_ptr作为参数的函数,c++,templates,smart-pointers,C++,Templates,Smart Pointers,我正在尝试编写一个函数,该函数接受从Base派生的类的unique_ptr作为指示所有权转移的参数。我想出了以下代码: #include <memory> #include <type_traits> class Base { public: Base() {} }; class Derived : public Base { public: Derived() {} }; void foo(std::unique_ptr<Deriv

我正在尝试编写一个函数,该函数接受从Base派生的类的unique_ptr作为指示所有权转移的参数。我想出了以下代码:

#include <memory>
#include <type_traits>

class Base
{
  public:
    Base() {}
};

class Derived : public Base
{
  public:
    Derived() {}
};


void foo(std::unique_ptr<Derived> _data) {}

template <class T>
void boo(std::unique_ptr<T> _data) {
    static_assert(std::is_convertible<T*, Base*>::value,
                  "Only classes derived from Base can be used as "
                  "parameter for boo");
}


int main() { foo(new Derived); }
还有智能指针

void foo_2(std::unique_ptr<Derived>& _data) {
     boo(std::move(_data)); 
}

std::unique_ptr<Derived> derived_2 = std::make_unique<Derived>();
// Do something with derived_2
foo(std::move(derived_2)); // Have to use `std::move`
                           // or
foo_2(derived_2);

第二个省略了新函数的需要并不像第一个那么简单,尽管我应该承认差异并没有那么大,可能2x类型的重载3和重载4在这里不适用。他们的签名是

unique_ptr( pointer p, /* see below */ d1 ) noexcept;

unique_ptr( pointer p, /* see below */ d2 ) noexcept;
它们接受第二个参数,即自定义删除器。唯一适用的重载是2,它是

explicit unique_ptr( pointer p ) noexcept;
因为它被标记为显式,所以它不会隐式地将指针转换为唯一的\u ptr。这是一个安全问题,明确说明是正确的。如果不明确的话

将进行编译,但这将是未定义的行为,因为当指针在foo结束时被销毁时,数据将尝试删除指针。

您必须在转换中明确:

int main()
{
    Derived* d = nullptr;
    BadInterface(&d); // mainly d = new Derived(..);
    foo(std::unique_ptr<Derived>(d));
}
在您的单衬里箱中:

foo(std::unique_ptr<Derived>(new Derived));

为什么不是foosd::make_unique?int main{foosd::make_unique;}有什么问题吗?@Ron我知道。但要称呼他们,我必须有独特的ptr。如果我将unique_ptr作为参数传递,调用data/releatse是没有意义的,因为所有权已经转移。如果我传递原始指针->我会得到编译错误。
int main()
{
    Derived* d = nullptr;
    BadInterface(&d); // mainly d = new Derived(..);
    foo(std::unique_ptr<Derived>(d));
}
foo(std::unique_ptr<Derived>(new Derived));