I have two questions concerning the helper class std::tuple_size<std::array>
of std::array
.
First, there is a constexpr size()
member function in class std::array
, why does one need std::tuple_size<std::array>
?
Second, is the name tuple_size
misleading?
The design goal of std::tuple_size
(and its friends std::tuple_element
and std::get
) is to work not only on literal std::tuple
s, but on anything tuple-like. Something being tuple-like generally just means that it is a compound type containing a fixed number of ordered elements.
You can clearly see this abstraction in use by looking, for example, at how structured bindings are defined : they allow decomposing anything that has sensible implementations of std::tuple_size
, std::tuple_element
and get<I>
.
Under this broadened notion of "tuple-like", it only makes sense that std::array
(and std::pair
) would specialize these traits to be handled as a tuple of N identical types (resp. a tuple of size 2).
It's part of the tuple interface, which std::array
supports. The other parts are std::tuple_element
and std::get
.
And std::array::size
is also redundant, the size is specified as part of the type. That exists as part of the sequence container interface.
std::tuple_size
and std::tuple_element
and function templates called get
provide a generic interface to "list of objects with constant count and types" which can be used in template programming without needing to specify types.
#include <utility>
template <class Tuple>
constexpr std::tuple_element_t<Tuple>& get_last(Tuple& t) {
constexpr auto size = std::tuple_size<Tuple>::value;
static_assert(size > 0);
return get<size-1>(t);
}
This get_last
function will work with std::tuple
, std::pair
, std::array
, and any other user types that provide specializations for std::tuple_size
, std::tuple_element
, and a function template get
in a namespace related to the type.
Also, the language itself looks for and uses std::tuple_size
, std::tuple_element
, and get
when the structured binding syntax is used. Again this can be any of the same types, including a user-defined type that implements the interface.
using MyVec = std::array<double, 3>;
void f(const MyVec& v) {
const auto& [x, y, z] = v;
// ...
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.