提问者:小点点

函数签名中未展开的参数包


较新的GCC引入了一个新的内置__integer_pack来帮助它实现std::make_integer_sequence和朋友。 由于原因(tm),我无法使用这个函数,所以我尝试重新实现它(然后使用#define替换标准库用法)

它以__integer_pack(N)...的形式使用,它扩展了它的“返回值”。 然而,我不能说服我自己的模板类型与此匹配,clang(10)错误的是:

error: pack expansion does not contain any unexpanded parameter packs

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

这有可能吗?

以下是我目前得到的信息:

#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>{});
}

共1个答案

匿名用户

不,这不可能。 __integer_pack不是函数,它是一个占位符,由编译器展开为参数包。 这是无法在语言中复制的。

您可以查看gcc如何实现用gcc/cp/pt.c中的扩展替换对__integer_pack的调用,当前从第3750行开始。 builtin_pack_fn_p()标识对__integer_pack的调用(_p后缀表示“谓词”),expand_integer_pack执行扩展。

您将需要在该语言中编写自己的实现(或复制现有的实现)。