Is specialization of std::tuple_size and std::tuple_element permitted for custom types?
I suppose it is, but I want to be absolutely sure, and I can't find any concrete information.
Example (namespaces, member functions and get<I> overloads omitted):
template <typename T, size_t N>
struct vector { T _data[N]; };
template<size_t I, typename T, size_t N>
constexpr T& get(vector<T,N>& vec) { return vec._data[I]; }
namespace std {
template<typename T, size_t N>
class tuple_size< vector<T,N> > : public std::integral_constant<size_t, N> { };
template<size_t I, typename T, size_t N>
class tuple_element< I, vector<T,N> > { public: using type = T; };
}
I need that for use with structured bindings:
void f(vector<T,3> const& vec)
{
auto& [x,y,z] = vec;
// stuff...
}
Specializations for user-defined types are generally fine, and always have been. N4606, [namespace.std]/1:
A program may add a template specialization for any standard library template to namespace
stdonly if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited.
For tuple_size, the requirements for the original template are specified in [tuple.helper]/1:
All specializations of
tuple_size<T>shall meet theUnaryTypeTraitrequirements with aBaseCharacteristicofintegral_constant<size_t, N>for someN.
UnaryTypeTrait, in turn, in [meta.rqmts]/1:
A UnaryTypeTrait describes a property of a type. It shall be a class template that takes one template type argument and, optionally, additional arguments that help define the property being described. It shall be
DefaultConstructible,CopyConstructible, and publicly and unambiguously derived, directly or indirectly, from its BaseCharacteristic, which is a specialization of the templateintegral_constant, with the arguments to the templateintegral_constantdetermined by the requirements for the particular property being described. The member names of the BaseCharacteristic shall not be hidden and shall be unambiguously available in the UnaryTypeTrait.
tuple_element's requirements are specified in [tuple.helper]/6 and [meta.rqmts]/3, but in the interest of brevity I won't post them here. Suffice to say that it is indeed legal to specialize...
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