How to access template parameters?

61 Views Asked by At

If I need to know template parameters in some other template which uses it, how can I access them?

Is the way below with the constexpr static size_t data_size the recommended approach or there is some syntax which could allow to get access from the data_user_typed to _data_size in ExtendableIndex without such constexpr static?

I know that is comes for free in term of the generated code, but, anyway, is it the recommended approach or this could be done in more straightforward way in the language?

Here is the demo

#include <array>

using data_type = int;

template<std::size_t _data_size>
struct ExtendableIndex
{
    constexpr static std::size_t data_size = _data_size;

    std::size_t index;
    std::array<data_type, _data_size> data;
};

template<>
struct ExtendableIndex<0>
{
    constexpr static std::size_t data_size = 0;

    std::size_t index;
};

constexpr std::size_t cache_length = 0;     // Can be set to any cache size including 0

using DefaultIndex = ExtendableIndex<cache_length>;

template<std::size_t _data_size>
ExtendableIndex<_data_size> data_user()
{
    ExtendableIndex<_data_size> index{};

    if constexpr (_data_size > 0)
    {
        auto value = index.data[0]; 
    }

    return index;
}

template<typename T>
T data_user_typed()
{
    T index{};

    if constexpr (T::data_size > 0)
    {
        auto value = index.data[0];
    }

    return index;
}

int main()
{
    auto index_one = data_user<cache_length>(); // Works, but requires passing length, not a type
    auto index_two = data_user<DefaultIndex::data_size>(); // Seems to be better
    auto index_three = data_user_typed<DefaultIndex>();  // Good, but still requires constexpr static data_size
} 
1

There are 1 best solutions below

1
HolyBlackCat On BEST ANSWER

The only other option is a template with a specialization to extract the argument:

template <typename T> struct GetSize {};
template <std::size_t N> struct GetSize<ExtendableIndex<N>> : std::integral_constant<std::size_t, N> {};

GetSize<ExtendableIndex<42>>::value == 42

Since this is more verbose, usually your approach is used.