absl::AnyInvocable
Synopsis
Declared in <absl/functional/any_invocable.h>
template<class Sig>
class AnyInvocable;
Description
absl::AnyInvocable is a functional wrapper type, like std::function, that assumes ownership of an invocable object. Unlike std::function, an absl::AnyInvocable is more type‐safe and provides the following additional benefits:
* Properly adheres to const correctness of the underlying type * Is move‐only so avoids concurrency problems with copied invocables and unnecessary copies in general. * Supports reference qualifiers allowing it to perform unique actions (noted below).
absl::AnyInvocable is a template, and an absl::AnyInvocable instantiation may wrap any invocable object with a compatible function signature, e.g. having arguments and return types convertible to types matching the absl::AnyInvocable signature, and also matching any stated reference qualifiers, as long as that type is moveable. It therefore provides broad type erasure for functional objects.
An absl::AnyInvocable is typically used as a type‐erased function parameter for accepting various functional objects:
// Define a function taking an AnyInvocable parameter. void my_func(absl::AnyInvocable<int()> f) { ... };
// That function can accept any invocable type:
// Accept a function reference. We don't need to move a reference. int func1() { return 0; }; my_func(func1);
// Accept a lambda. We use std::move here because otherwise my_func would // copy the lambda. auto lambda = { return 0; }; my_func(std::move(lambda));
// Accept a function pointer. We don't need to move a function pointer. func2 = &func1; my_func(func2);
// Accept an std::function by moving it. Note that the lambda is copyable // (satisfying std::function requirements) and moveable (satisfying // absl::AnyInvocable requirements). std::function<int()> func6 = { return 0; }; my_func(std::move(func6));
AnyInvocable also properly respects const qualifiers, reference qualifiers, and the noexcept specification as part of the user‐specified function type (e.g. AnyInvocable<void() const && noexcept>). These qualifiers will be applied to the AnyInvocable object's operator(), and the underlying invocable must be compatible with those qualifiers.
Comparison of const and non‐const function types:
// Store a closure inside of func with the function type int(). // Note that we have made func itself const. const AnyInvocable<int()> func = { return 0; };
func(); // Compile‐error: the passed type int() isn't const.
// Store a closure inside of const_func with the function type // int() const. // Note that we have also made const_func itself const. const AnyInvocable<int() const> const_func = { return 0; };
const_func(); // Fine: int() const is const.
In the above example, the call func() would have compiled if std::function were used even though the types are not const compatible. This is a bug, and using absl::AnyInvocable properly detects that bug.
In addition to affecting the signature of operator(), the const and reference qualifiers of the function type also appropriately constrain which kinds of invocable objects you are allowed to place into the AnyInvocable instance. If you specify a function type that is const‐qualified, then anything that you attempt to put into the AnyInvocable must be callable on a const instance of that type.
Constraint example:
// Fine because the lambda is callable when const. AnyInvocable<int() const> func = [=]{ return 0; };
// This is a compile‐error because the lambda isn't callable when const. AnyInvocable<int() const> error = [=] mutable { return 0; };
An && qualifier can be used to express that an absl::AnyInvocable instance should be invoked at most once:
// Invokes continuation with the logical result of an operation when // that operation completes (common in asynchronous code). void CallOnCompletion(AnyInvocable<void(int)&&> continuation) { int result_of_foo = foo();
// std::move is required because the operator() of continuation is // rvalue‐reference qualified. std::move(continuation)(result_of_foo); }
Attempting to call absl::AnyInvocable multiple times in such a case results in undefined behavior.
Invoking an empty absl::AnyInvocable results in undefined behavior:
// Create an empty instance using the default constructor. AnyInvocable<void()> empty; empty(); // WARNING: Undefined behavior!
Type Aliases
Name |
Description |
Tag indicating that |
|
The return type of Sig. |
Member Functions
Name |
Description |
|
Constructors |
|
If not empty, destroys the target. |
Assignment operators |
|
absl::AnyInvocable::swap() |
|
absl::AnyInvocable::operator bool() |
Using Declarations
Name |
Friends
Name |
Description |
Grants friendship to other |
|
swap() |
|
Returns |
|
Returns |
|
Returns |
|
Returns |
Created with MrDocs