将原始指针传递给接受 unique_ptr 作为参数的函数
Pass raw pointer to function that accepts unique_ptr as parameter
我正在尝试编写一个函数,它接受从 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); }
但是当我尝试编译它时,我得到一个错误,告诉我如果我使用 foo
could not convert ‘(operator new(1ul), (<statement>, ((Derived*)<anonymous>)))’ from ‘Derived*’ to ‘std::unique_ptr<Derived>’
并且当我使用 boo
时也是如此(加上一些模板细节) .如果我理解正确,我被告知 std::unique_ptr<Derived>
没有可以接受 Derived
指针的构造函数。但是当我查看 unqiue_ptr 构造函数的 cppreference page 时,我看到有这样的构造函数(编号 3-4)。
问题是:如何创建一个接受 unique_ptr
作为参数并使用原始指针调用它的函数。
P.S. 我正在尝试编写一个接受 unique_ptr
的函数,因为我想表明参数的所有权将被转移。如果您知道如何编写一个带有签名的函数,可以清楚明确地表明所有权正在转移,我也会接受这个作为答案。此函数可以使用 static_assert
模板或使用 Base
指针作为参数。
P.S.主要问题是如何制作foo(new Derived)
。我知道我可以使用 boo(std::make_unique<Derived>())
(在那种情况下一切正常)但我也 真的 想知道为什么带有原始指针的示例不起作用,因为我不知道如何表明我正在“窃取”原始指针的所有权。
P.S 用法示例(使用原始指针)(不起作用)
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
还有智能指针
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;
由于它被标记为显式,因此它不会隐式地将指针转换为 unique_ptr
。这是一个安全问题,明确说明是正确的。如果不是 explicit
那么
void foo(std::unique_ptr<int> _data) {}
int main()
{
int bar;
foo(&bar);
}
会编译,但它是未定义的行为,因为 _data
会在指针在 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));
我正在尝试编写一个函数,它接受从 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); }
但是当我尝试编译它时,我得到一个错误,告诉我如果我使用 foo
could not convert ‘(operator new(1ul), (<statement>, ((Derived*)<anonymous>)))’ from ‘Derived*’ to ‘std::unique_ptr<Derived>’
并且当我使用 boo
时也是如此(加上一些模板细节) .如果我理解正确,我被告知 std::unique_ptr<Derived>
没有可以接受 Derived
指针的构造函数。但是当我查看 unqiue_ptr 构造函数的 cppreference page 时,我看到有这样的构造函数(编号 3-4)。
问题是:如何创建一个接受 unique_ptr
作为参数并使用原始指针调用它的函数。
P.S. 我正在尝试编写一个接受 unique_ptr
的函数,因为我想表明参数的所有权将被转移。如果您知道如何编写一个带有签名的函数,可以清楚明确地表明所有权正在转移,我也会接受这个作为答案。此函数可以使用 static_assert
模板或使用 Base
指针作为参数。
P.S.主要问题是如何制作foo(new Derived)
。我知道我可以使用 boo(std::make_unique<Derived>())
(在那种情况下一切正常)但我也 真的 想知道为什么带有原始指针的示例不起作用,因为我不知道如何表明我正在“窃取”原始指针的所有权。
P.S 用法示例(使用原始指针)(不起作用)
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
还有智能指针
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;
由于它被标记为显式,因此它不会隐式地将指针转换为 unique_ptr
。这是一个安全问题,明确说明是正确的。如果不是 explicit
那么
void foo(std::unique_ptr<int> _data) {}
int main()
{
int bar;
foo(&bar);
}
会编译,但它是未定义的行为,因为 _data
会在指针在 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));