std::function(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’– NAME πŸ’–

okay bestie, this is the std::function(3) page from the C++ Standard Libary manual (their spelling, not mine πŸ’…). The actual name is short and iconic:

  • std::function β€” std::function

✨ Synopsis ✨

Defined in header <functional>
template< class >                   (since C++11)
class function; /* undefined */
template< class R, class... Args >  (since C++11)
class function<R(Args...)>;

Class template std::function is a general-purpose polymorphic function wrapper. No cap.

Instances of std::function can store, copy, and invoke any CopyConstructible Callable target -- functions (via pointers thereto), lambda expressions, bind expressions, or other function objects, as well as pointers to member functions and pointers to data members.

The stored callable object is called the target of std::function. If a std::function contains no target, it is called empty. Invoking the target of an empty std::function results in std::bad_function_call exception being thrown. That's the "bestie why" exception, fr fr.

std::function satisfies the requirements of CopyConstructible and CopyAssignable. Slay.


πŸŽ€ Member types πŸŽ€

  • result_type β€” R
  • argument_type (deprecated in C++17)(removed in C++20) β€” T if sizeof...(Args)==1 and T is the first and only type in Args...
  • first_argument_type (deprecated in C++17)(removed in C++20) β€” T1 if sizeof...(Args)==2 and T1 is the first of the two types in Args...
  • second_argument_type (deprecated in C++17)(removed in C++20) β€” T2 if sizeof...(Args)==2 and T2 is the second of the two types in Args...

πŸ’… Member functions πŸ’…

  • constructor β€” constructs a new std::function instance (public member function)
  • destructor β€” destroys a std::function instance (public member function)
  • operator= β€” assigns a new target (public member function)
  • swap β€” swaps the contents (public member function)
  • assign (removed in C++17) β€” assigns a new target (public member function)
  • operator bool β€” checks if a target is contained (public member function)
  • operator() β€” invokes the target (public member function)

πŸ¦‹ Target access πŸ¦‹

  • target_type β€” obtains the typeid of the stored target (public member function)
  • target β€” obtains a pointer to the stored target (public member function)

πŸ”₯ Non-member functions πŸ”₯

  • std::swap(std::function) β€” specializes the std::swap algorithm (C++11) (function template)
  • operator== β€” compares a std::function with nullptr
  • operator!= β€” (function template) (removed in C++20)

πŸ‘‘ Helper classes πŸ‘‘

  • std::uses_allocator<std::function> β€” specializes the std::uses_allocator type trait (C++11) (until C++17) (class template specialization)
  • Deduction guides (since C++17)

🧚 Notes 🧚

Care should be taken when a std::function, whose result type is a reference, is initialized from a lambda expression without a trailing-return-type. Due to the way auto deduction works, such lambda (until C++23) expression will always return a prvalue. Hence, the resulting reference will usually bind to a temporary whose lifetime ends when std::function::operator() returns.

If a std::function returning a reference is initialized from a function or function object returning a prvalue (including a lambda expression without a trailing-return-type), the program is ill-formed (since C++23) because binding the returned reference to a temporary object is forbidden.

🚨 bestie, this is the part where the compiler can absolutely ruin your whole afternoon. Read it twice, okay?
std::function<const int&()> F([] { return 42; }); // Error since C++23: can't bind
                                                   // the returned reference to a temporary
int x = F(); // Undefined behavior until C++23: the result of F() is a dangling reference

std::function<int&()> G([]() -> int& { static int i{0x2A}; return i; }); // OK

std::function<const int&()> H([i{052}] -> const int& { return i; }); // OK

🌈 Example 🌈

Run this code β€” that's literally what the page says, so go off, bestie:

#include <functional>
#include <iostream>

struct Foo
{
    Foo(int num) : num_(num) {}
    void print_add(int i) const { std::cout << num_ + i << '\n'; }
    int num_;
};

void print_num(int i)
{
    std::cout << i << '\n';
}

struct PrintNum
{
    void operator()(int i) const
    {
        std::cout << i << '\n';
    }
};

int main()
{
    // store a free function
    std::function<void(int)> f_display = print_num;
    f_display(-9);

    // store a lambda
    std::function<void()> f_display_42 = []() { print_num(42); };
    f_display_42();

    // store the result of a call to std::bind
    std::function<void()> f_display_31337 = std::bind(print_num, 31337);
    f_display_31337();

    // store a call to a member function
    std::function<void(const Foo&, int)> f_add_display = &Foo::print_add;
    const Foo foo(314159);
    f_add_display(foo, 1);
    f_add_display(314159, 1);

    // store a call to a data member accessor
    std::function<int(Foo const&)> f_num = &Foo::num_;
    std::cout << "num_: " << f_num(foo) << '\n';

    // store a call to a member function and object
    using std::placeholders::_1;
    std::function<void(int)> f_add_display2 = std::bind(&Foo::print_add, foo, _1);
    f_add_display2(2);

    // store a call to a member function and object ptr
    std::function<void(int)> f_add_display3 = std::bind(&Foo::print_add, &foo, _1);
    f_add_display3(3);

    // store a call to a function object
    std::function<void(int)> f_display_obj = PrintNum();
    f_display_obj(18);

    auto factorial = [](int n)
    {
        // store a lambda object to emulate "recursive lambda"; aware of extra overhead
        std::function<int(int)> fac = [&](int n) { return (n < 2) ? 1 : n * fac(n - 1); };
        // note that "auto fac = [&](int n) {...};" does not work in recursive calls
        return fac(n);
    };
    for (int i{5}; i != 8; ++i)
        std::cout << i << "! = " << factorial(i) << ";  ";
    std::cout << '\n';
}

πŸ“ Possible output πŸ“

-9
42
31337
314160
314160
num_: 314159
314161
314162
18
5! = 120;  6! = 720;  7! = 5040;

πŸ’œ See also πŸ’œ

  • move_only_function β€” wraps callable object of any type with specified function call signature (C++23) (class template)
  • bad_function_call β€” the exception thrown when invoking an empty std::function (C++11) (class)
  • mem_fn β€” creates a function object out of a pointer to a member (C++11) (function template)
  • typeid β€” queries information of a type, returning a std::type_info object representing the type

πŸ’– source/version: http://cppreference.com Β· date: 2024.06.10 Β· manual: std::function(3) β€” periodt, bestie πŸ’–

πŸ“¦ where this page comes from