class foo {
foo();
unique_ptr<T, (void *)(T*)> ptr;
};
foo::foo() {
bool x = some operation;
if (!x) throw;
ptr = unique_ptr<T, (void *)(T*)>(new T(x), deleter);
}
此代码无法编译,因为唯一指针及其删除器使用 null 进行初始化(因为我不会在初始值设定项列表中初始化它)。我无法在列表中初始化它,因为它依赖于变量x
如上所示。如何解决此僵局?
试试这个:
foo()
: ptr(nullptr, deleter)
{
if (!some operation) { throw AppropriateException(); }
ptr.reset(new T(true));
}
一种解决方案是添加一个静态函数来确定x
应该是什么,然后将其返回到成员初始化列表中unique_ptr
的构造函数
foo() : ptr(construct_t(), deleter) {}
static T* construct_t()
{
bool x = some operation;
if(!x) throw;
return new T(x);
}
使用生成器和自定义删除器的工作示例:
#include <iostream>
#include <memory>
#include <vector>
struct bar {};
struct bar_deleter {
void operator()(bar* p) const noexcept {
try {
if (p) {
std::cout << "deleting p" << std::endl;
}
else {
std::cout << "not deleting p" << std::endl;
}
}
catch(...) {
}
}
};
bool some_condition()
{
static int counter = 0;
return (counter++ % 2) == 0;
}
struct foo {
using ptr_type = std::unique_ptr<bar, bar_deleter>;
foo()
: ptr(bar_generator())
{}
static ptr_type bar_generator() {
if (some_condition()) {
std::cout << "creating bar" << std::endl;
return { new bar, bar_deleter{} };
}
else {
std::cout << "not creating bar" << std::endl;
return { nullptr, bar_deleter{} };
}
}
ptr_type ptr;
};
int main()
{
using namespace std;
auto v = std::vector<foo>(10);
return 0;
}
预期成果:
creating bar
not creating bar
creating bar
not creating bar
creating bar
not creating bar
creating bar
not creating bar
creating bar
not creating bar
deleting p
deleting p
deleting p
deleting p
deleting p