In trying to learn how to use std::aligned_union I am having trouble finding any examples. My attempt is running into problems that I do not know how to solve.
struct include
{
std::string file;
};
struct use
{
use(const std::string &from, const std::string &to) : from{ from }, to{ to }
{
}
std::string from;
std::string to;
};
std::aligned_union<sizeof(use), include, use>::type item;
*reinterpret_cast<use*>(&item_) = use{ from, to };
When I attempt to run the program in VC++2013 debug mode I get a runtime error in memcpy(unsigned char * dst, unsigned char * src, unsigned long count)
. I assume that this is how VC++ implements the assignment from the temporary.
How would I change this so that I do not have this issue?
The aligned_union
type gives you a POD type that's suitable as storage for the desired classes - it is not actually an object of that type. You still have to construct your own object:
#include <memory>
{
std::aligned_union<sizeof(use), include, use>::type storage;
use * p = new (static_cast<void*>(std::addressof(storage))) use(from, to);
// ...
p->~use();
}
Expanding on Kerrek's answer: I suggest using unique_ptr
with custom deleter to handle the destruction for you automatically. You can wrap everything up nicely in a factory (Live at Rextester):
struct placement_deleter {
template <typename T>
void operator () (T* ptr) const {
ptr->~T();
}
};
template <typename T, typename...Args>
std::unique_ptr<T, placement_deleter>
make_in_place(void* place, Args&&...args) {
return std::unique_ptr<T, placement_deleter>{
::new (place) T(std::forward<Args>(args)...)
};
}
int main() {
std::aligned_union<0, int, std::string>::type storage;
{
auto i = make_in_place<int>(&storage, 42);
std::cout << *i << '\n';
}
{
auto s = make_in_place<std::string>(&storage, "this is");
*s += " a test";
std::cout << *s << '\n';
}
}
I'm also expanding on Kerrek's answer. A possible (C++14) implementation of aligned_union
is:
template <std::size_t Len, class... Types>
struct aligned_union
{
static constexpr std::size_t alignment_value = std::max({alignof(Types)...});
struct type
{
alignas(alignment_value) char _s[std::max({Len, sizeof(Types)...})];
};
};
So it's clear that:
type
is a POD type of a size and alignment suitable for use as uninitialized storage for an object of any of the types listed in Types
(but actually none of those types)Len
parameter (I think it's for generic programming situations, e.g. see https://stackoverflow.com/a/27069379/3235496)For further details:
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