Info
-
Did you know about C++20
is_layout_compatible_v
type_trait?
Example
struct foo {
int a{};
int b{};
};
struct bar {
const int x{};
int y{};
};
struct baz : bar { };
struct other {
int a{};
char b[4]{};
};
static_assert(not std::is_layout_compatible_v<void, int>);
static_assert(not std::is_layout_compatible_v<const int*, const int&>);
static_assert(std::is_layout_compatible_v<const int, int const volatile>);
static_assert(std::is_layout_compatible_v<foo, bar>);
static_assert(std::is_layout_compatible_v<foo, baz>);
static_assert(std::is_layout_compatible_v<bar, baz>);
static_assert(not std::is_layout_compatible_v<bar, other>);
static_assert(not std::is_layout_compatible_v<bar, void>);
Puzzle
Can you implemtn
count_compatible
which returns the number of compatible types to the given one?
template<class T, class... Ts>
constexpr auto count_compatible = 0; // TODO
static_assert(0 == count_compatible<int, const int*, const int&, volatile int*, int()>);
static_assert(0 == count_compatible<void*, volatile void*, const volatile void*, volatile const void* const>);
static_assert(0 == count_compatible<void, int>);
static_assert(1 == count_compatible<int, int>);
static_assert(1 == count_compatible<int, float, int>);
static_assert(2 == count_compatible<int, short, signed int, unsigned int, int const>);
static_assert(4 == count_compatible<int, int, const int, int const, unsigned const, signed const int>);
Solutions
template<class T, class... Ts>
constexpr auto count_compatible = (std::is_layout_compatible_v<T, Ts> + ... + std::size_t{});
template<class T, class... Ts>
constexpr auto count_compatible = []{
return (std::is_layout_compatible_v<T, Ts> + ...);
}();
template<class T, class... Ts>
constexpr auto count_compatible = (... + std::is_layout_compatible_v<T, Ts>);