<xstd/misc/type_traits/empty_base_type.hpp>¶
xstd::empty_base_type¶
template<class Tag = void>
struct empty_base_type {};
A tagged empty class that keeps the place of a base class that is not there.
Template parameters¶
| Parameter | Meaning |
|---|---|
Tag |
Distinguishes one empty base from another. Defaults to void, and distinct tags give distinct types, so a class can derive from more than one. |
Notes¶
- It is an empty, regular, trivial class, whose special members do not throw.
- It declares no comparison, so none reaches a class derived from it.
Example¶
#include <xstd/misc/type_traits/empty_base_type.hpp> // empty_base_type
#include <iostream> // boolalpha, cout
#include <type_traits> // conditional_t
struct use_count
{
int uses = 0;
};
// A widget counts its uses only where Counted holds, and where it does not its base costs no storage.
template<bool Counted>
struct widget : std::conditional_t<Counted, use_count, xstd::empty_base_type<use_count>>
{
int id = 0;
};
// Whether a class counts its uses, read from whether it has the member that counts them.
template<class T>
concept counts_uses = requires (T const& t) { t.uses; };
auto main() -> int
{
auto counted = widget<true>();
++counted.uses;
std::cout << "uses: " << counted.uses << '\n';
std::cout << std::boolalpha;
std::cout << "widget<true> counts its uses: " << counts_uses<widget<true>> << '\n';
std::cout << "widget<false> counts its uses: " << counts_uses<widget<false>> << '\n';
std::cout << "sizeof(widget<false>) == sizeof(int) is " << (sizeof(widget<false>) == sizeof(int)) << '\n';
}
Output:
uses: 1
widget<true> counts its uses: true
widget<false> counts its uses: false
sizeof(widget<false>) == sizeof(int) is true
See also¶
| Entity | Relation |
|---|---|
empty_member_type |
the same for a data member, and comparable |
conditional_data_member |
a member's type, or an empty type where a condition fails |