TransWikia.com

Unexpanded parameter pack in function signature

Stack Overflow Asked on November 4, 2021

Newer GCC introduced a new builtin __integer_pack to help it implement std::make_integer_sequence and friends. For Reasons(tm), I am unable to use this function, so I’m trying to reimplement it (and then use #define to replace the standard library usage)

It’s used in the form __integer_pack(N)..., which expands its "return value". However I can’t convince the type of my own templates to match this, with clang (10) erroring with:

error: pack expansion does not contain any unexpanded parameter packs

using make_integer_sequence = integer_sequence<_Tp, integer_pack(_Num)...>;

Is this even possible?

Here’s what I’ve got so far:

#include <cstddef>


template <std::size_t...> struct index_sequence {};

template <std::size_t N, std::size_t... Is>
struct integer_pack : integer_pack<N - 1, N - 1, Is...> {};

template <std::size_t... Is>
struct integer_pack<0u, Is...> : index_sequence<Is...> { using type = index_sequence<Is...>; };


// Assume nothing below here can be changed.
#include <iostream>

/// Class template integer_sequence
template<typename _Tp, _Tp... _Idx>
struct integer_sequence
{
    typedef _Tp value_type;
    static constexpr size_t size() noexcept { return sizeof...(_Idx); }
};

// debugging aid
template<typename T, T... ints>
void print_sequence(integer_sequence<T, ints...> int_seq)
{
    std::cout << "The sequence of size " << int_seq.size() << ": ";
    ((std::cout << ints << ' '),...);
    std::cout << 'n';
}

template<typename _Tp, _Tp _Num>
using make_integer_sequence = integer_sequence<_Tp, integer_pack(_Num)...>;

int main()
{
    print_sequence(make_integer_sequence<int, 20>{});
}

One Answer

No, this is not possible. __integer_pack is not a function, it is a placeholder that is expanded by the compiler into a parameter pack. This is not something you can replicate within the language.

You can look at how gcc implements replacing the call to __integer_pack with its expansion in gcc/cp/pt.c, starting at line 3750 currently. builtin_pack_fn_p() identifies calls to __integer_pack (the _p suffix means "predicate"), and expand_integer_pack performs the expansion.

You will need to write your own implementation (or copy an existing one) within the language.

Answered by ecatmur on November 4, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP