C++ 将原始指针传递给接受unique_ptr作为参数的函数
我正在尝试编写一个函数,该函数接受从Base派生的类的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
#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));