Info
-
Did you know that C++20 added support for
[[no_unique_address]]
attribute?
Example
struct empty {};
struct ebco : empty {}; // Empty Base Class Optimization (EBCO)
static_assert(sizeof(empty) == 1);
static_assert(sizeof(ebco) == 1);
struct no_unique_address {
[[no_unique_address]] struct {} empty;
};
static_assert(sizeof(no_unique_address) == 1);
Puzzle
-
Can you add an optional field of type
T
tofoo
only whenEnable == true
?- Preferably by leveraging
[[no_unique_address]]
attribute
- Preferably by leveraging
template<auto Enable, class T = void>
struct [[gnu::packed]] foo {
int i{};
bool b{};
/*TODO - optional field of type T when Enabled */
};
static_assert(sizeof(int) + sizeof(bool) == sizeof(foo<false>));
static_assert(sizeof(int) + sizeof(bool) + sizeof(int) == sizeof(foo<true, int>));
struct bar{};
static_assert(sizeof(int) + sizeof(bool) == sizeof(foo<true, bar>));
struct baz{ int i{}; };
static_assert(sizeof(int) + sizeof(bool) + sizeof(baz) == sizeof(foo<true, baz>));
Solutions
namespace detail {
struct disabled{};
template <auto Enable, class T>
using when_enabled_t = std::conditional_t<Enable, T, disabled>;
}
template<auto Enable, class T = void>
struct [[gnu::packed]] foo {
int i{};
bool b{};
[[no_unique_address]] detail::when_enabled_t<Enable, T> t{};
};
template<auto Enable, class T = void>
struct [[gnu::packed]] foo {
int i{};
bool b{};
struct empty{};
[[no_unique_address]] std::conditional_t<Enable, T, empty> c;
};
template<auto Enable, class T = void>
struct [[gnu::packed]] foo {
int i{};
bool b{};
};
template<class T>
struct [[gnu::packed]] foo<true,T> {
int i{};
bool b{};
[[no_unique_address]] T t{};
};
template<auto Enable, class T = void>
struct [[gnu::packed]] foo {
int i{};
bool b{};
[[no_unique_address]] std::conditional_t<Enable, T, std::tuple<>> t{};
};