admin管理员组

文章数量:1122846

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 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.

Share Improve this question asked Nov 22, 2024 at 17:10 HenryHenry 5873 silver badges13 bronze badges 3
  • is use_cache known at compile time ? constexpr ? Or is it dynamic. – Ahmed AEK Commented Nov 22, 2024 at 18:49
  • Your best option is std::optional that you only emplace in the false path, otherwise you will have to use some callback, which is not pretty – Ahmed AEK Commented Nov 22, 2024 at 18:53
  • @AhmedAEK I use callback finally because I am using C++14, but I will try to explore std::optional in future. You can answer this question, so that I can close this question. Thanks a lot. – Henry Commented Nov 25, 2024 at 8:40
Add a comment  | 

1 Answer 1

Reset to default 1

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);
    }

}

本文标签: cManaging the Lifecycle of re2RE2 Objects with Cached and StackAllocated OptionsStack Overflow