Kam*_*nji 0 c++ templates smart-pointers
我正在尝试编写一个函数,接受unique_ptr到Base作为参数派生的类(表示所有权转移).我想出了以下代码:
#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); }
Run Code Online (Sandbox Code Playgroud)
但是当我尝试编译它时,我得到并且错误地告诉我,could not convert ‘(operator new(1ul), (<statement>, ((Derived*)<anonymous>)))’ from ‘Derived*’ to ‘std::unique_ptr<Derived>’如果我在使用时使用foo和相同(加上一些模板细节)boo.如果我正确地理解了一切,我被告知的是没有构造函数std::unique_ptr<Derived>可以接受指针Derived.但是当我在unppue_ptr构造函数的cppreference 页面上查看时,我看到有这样的构造函数(编号3-4).
问题是:我如何创建一个接受unique_ptr参数的函数并用原始指针调用它.
PS我正在尝试编写一个接受的函数,unique_ptr因为我想表明参数的所有权将被转移.如果您知道如何编写一个带有签名的函数,该签名可以清楚明确地表明所有权正在转移,我也会接受这个作为答案.此函数可以使用static_assert或使用Base指针作为参数进行模板.
PS主要问题是如何制作foo(new Derived).我知道我可以使用boo(std::make_unique<Derived>())(在这种情况下一切正常)但我也真的想知道为什么带有原始指针的例子不起作用,因为我不知道如何表明我正在"窃取"原始指针的所有权.
PS使用示例(带原始指针)(不工作)
Derived* derived_1 = new Derived;
// Do something with derived_1
boo(derived_1); // Pass to function and don't worry about `delete`
// because you know that ownership has been
// transferred and no longer is your concern
Run Code Online (Sandbox Code Playgroud)
并有智能指针
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);
Run Code Online (Sandbox Code Playgroud)
第二个(省略对新功能的需求)并不像第一个那么简单(尽管我应该承认差异不是那么大(可能是2x打字))
过载3和4不适用于此处.他们的签名是
unique_ptr( pointer p, /* see below */ d1 ) noexcept;
unique_ptr( pointer p, /* see below */ d2 ) noexcept;
Run Code Online (Sandbox Code Playgroud)
它们采用第二个参数,即自定义删除器.唯一适用的重载是2
explicit unique_ptr( pointer p ) noexcept;
Run Code Online (Sandbox Code Playgroud)
由于它被标记为显式,因此不会将指针隐式转换为a unique_ptr.这是一个安全问题,明确说明是正确的.如果不是explicit那么的话
void foo(std::unique_ptr<int> _data) {}
int main()
{
int bar;
foo(&bar);
}
Run Code Online (Sandbox Code Playgroud)
会编译,但它将是未定义的行为,因为_data尝试删除指针在它结束时被销毁foo.