我有一个函数
re02_match(regexp, use_cache, ...)
,我需要根据是否应使用缓存对象re2::RE2 objects
或应创建堆栈分配对象(use_cache = true)
来不同地处理(use_cache = false)
。我想避免为 re2::RE2 objects
进行堆分配。
这是我迄今为止尝试过的片段:
re2::RE2 *re02;
if (use_cache) {
//re2_get_cache() will return a shared_ptr<RE2>
re02 = re2_get_cache(regexp).get();
} else {
re2::RE2::Options options;
re2::RE2 re02_in_stack(regexp, options);
re02 = &re02_in_stack;
}
// Work with *re02
// ...
但是,我知道这种方法是有缺陷的,因为
re02_in_stack
的生命周期仅限于它定义的范围,并且以这种方式在shared_ptr上使用.get()
是有问题的。
如何正确管理 re2::RE2 objects
的生命周期,避免堆分配并确保对象在 re02_match
的整个执行过程中有效且可访问?任何见解或替代方法将不胜感激。
我心里有两个选择。
首先使用 std::Optional 并且仅
emplace
它位于错误路径中。
#include <iostream>
#include <optional>
struct Foo
{
void Bar(int c)
{
std::cout << "called with: " << c << '\n';
}
};
int main()
{
int value = 5;
bool use_cache = true;
std::optional<Foo> foo_opt;
std::shared_ptr<Foo> foo_ptr;
Foo* foo;
if (use_cache)
{
foo_ptr = std::make_shared<Foo>();
foo = foo_ptr.get();
}
else
{
foo_opt.emplace(); // constructor args here
foo = &(*foo_opt);
}
foo->Bar(value);
}
第二个选项是使用在两个分支中调用的回调。
#include <iostream>
#include <optional>
struct Foo
{
void Bar(int c)
{
std::cout << "called with: " << c << '\n';
}
};
int main()
{
int value = 5;
bool use_cache = true;
auto action = [&](Foo& foo)
{
foo.Bar(value);
};
if (use_cache)
{
auto foo_ptr = std::make_shared<Foo>();
action(*foo_ptr);
}
else
{
Foo foo;
action(foo);
}
}