c++functionlambdasmart-pointers

How to put std::function in a smart pointer like std::unique_ptr and use it?


How to put std::function in a smart pointer like std::unique_ptr and use it?
I have already tried but it didn't work.

Here is the code that I tried already:

const inline void PrintSection(TurboINI::types::section &section)
{
    std::cout << "[\"" << section.GetKey() << "\"]\n";

    auto PrintSectionContent =
        std::make_unique<std::function<void(TurboINI::types::section &)>>([&](TurboINI::types::section &_section) {
            if (!section.GetIntegers().empty())
            {
                for (const auto &i : _section.GetIntegers())
                {
                    std::cout << '\t';
                    PrintInteger(i);
                }
            }

            if (!section.GetStrings().empty())
            {
                for (const auto &i : _section.GetStrings())
                {
                    std::cout << '\t';
                    PrintString(i);
                }
            }
        });

    PrintSectionContent(section);
}

Solution

  • How to put std::function in a smart pointer like std::unique_ptr

    What you've already done is ok:

    auto PrintSectionContent =
        std::make_unique<std::function<void(TurboINI::types::section &)>>(
            [&](TurboINI::types::section &_section) {
                //....       
            });
    

    and use it?

    You can dereference the smart pointer and call the stored function in different ways. Here are two examples:

    (*PrintSectionContent)(section);          // 1
    PrintSectionContent->operator()(section); // 2
    

    The reason for (...) around *PrintSectionContent in the first variant is because of operator precedence. The function call has higher precedence (2) than indirection/dereferencing (3), which makes *PrintSectionContent(section) the same as ...

    *(PrintSectionContent(section));
    

    ... which tries to call the unique_ptr (not what it's pointing at) and then dereference the result of that call. You want to dereference the pointer to get a reference to the stored function and then call that.

    PrintSectionContent(section); that you have in the question has the same initial mistake but without trying to dereference the value returned by calling the unique_ptr.