I have a function re02_match(regexp, use_cache, ...)
where I need to handle re2::RE2 objects
differently based on whether a cached object should be used (use_cache = true)
or a stack-allocated object should be created (use_cache = false)
. I want to avoid heap allocation for the re2::RE2 objects
.
Here's a snippet of what I've tried so far:
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
// ...
However, I understand that this approach is flawed because the lifetime of re02_in_stack
is limited to the scope in which it is defined, and using .get()
on a shared_ptr in this manner is problematic.
How can I correctly manage the lifecycle of re2::RE2 objects
in a way that avoids heap allocation and ensures that the objects are valid and accessible throughout the execution of re02_match
? Any insights or alternative approaches would be greatly appreciated.
I have two options in mind.
first is using an std::optional and only emplace
it in the false path.
#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 = nullptr;
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);
}
the second option is to use a callback that you call in both branches, the disadvantage is that the order of code is reversed, with code appearing first happening last.
#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);
}
}