Reputation: 1173
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...
}
Upvotes: 22
Views: 2273
Reputation: 62975
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
std
only 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 theUnaryTypeTrait
requirements with aBaseCharacteristic
ofintegral_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_constant
determined 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...
Upvotes: 21