type_t might also be used to force specific type in variadic case:
template <typename ... Ts>
struct Example
{
#if 0
// "Alternative" ways:
// No type checks (and might be problematic with copy constructor)
template <typename ... Us> Example(Us&&...);
// SFINAE way
// Allows indeed to pass initial types, but verbose
// and condition might be non trivial
template <typename ... Us,
std::enable_if_t<(std::is_constructible<std::string, Us>&& ...), int> = 0>
Example(Us&&...);
#else
// Bonus: non template, so we might use {} is the call:
// Example<int, int>("next is empty", {})
Example(type_t<const std::string&, Ts>... args) : names{args...} {}
#endif
std::array<std::string, sizeof...(Ts)> names;
};
type_t
might also be used to force specific type in variadic case:or (with also
index_constant
)