简体   繁体   中英

What is the purpose of `std::tuple_size<std::array>`

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM