Consider the case in which I've enough storage to host a void *
and therefore to construct in-place a pointer.
Is there any guarantee that the same storage is big enough to always store also an std::reference_wrapper
?
Kind of (written out of my mind, just to give a grasp of what I mean):
std::aligned_storage_t<sizeof(void *), alignof(void *)> storage;
// ...
int value = 0;
new (&storage) std::reference_wrapper<int>{value};
From a quick and dirty test, I see that on my machine this is valid, that is the size of an std::reference_wrapper
fits with that of a void *
. However it could be the case on different platforms. At the same time, I cannot find any clue in the standard about the size of and std::reference_wrapper
and I'm wondering if it's implementation defined or there are any guarantees.
To give a context, I'm working on an opaque wrapper around different types (similar to std::any
) that performs a small object optimization to avoid allocations when possible.
When I receive an std::reference_wrapper
, I want to use a different path than that used to differentiate sizeof(T) > sizeof(void *)
from the other case around. However, I don't know if I can just copy construct in-place the wrapper or if I should rely on allocations also in this case instead.
A reference_wrapper can be used to store references in standard containers, and to pass objects by reference to std::bind . The type Ty must be an object type or a function type, or a static assert fails at compile time. The helper functions std::ref and std::cref can be used to create reference_wrapper objects.
(since C++11) std::reference_wrapper is a class template that wraps a reference in a copyable, assignable object. It is frequently used as a mechanism to store references inside standard containers (like std::vector) which cannot normally hold references.
The C++ standard does not pose any size requirements. Per [refwrap]
reference_wrapper<T>
is a Cpp17CopyConstructible and Cpp17CopyAssignable wrapper around a reference to an object or function of typeT
.reference_wrapper<T>
is a trivially copyable type.
All we know is that is copyable, and it is trivial. Other than that it it left up to the implementation. Typically it is just a wrapper for a T*
, but the implementation might have some other members in there for some reason
There is no guarantee in the standard.
No sensible implementation is going to use more than a pointer.
static_assert
it fits and you have enough alignment so your code is correct (and people can see it is correct). That static assert won't ever be hit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With