使用 std::index_sequence 的默认参数

Using default arguments for std::index_sequence

我很难理解以下内容。为什么这段代码编译

template <size_t N, size_t... N_i, size_t... M_i>
auto foo2(std::index_sequence<M_i...> = std::make_index_sequence<N>())
{

    constexpr size_t values[] = {N_i...};
    return A<values[M_i]...>();
}


template <size_t N,size_t... N_i>
auto foo()
{
    return foo2<N,N_i...>(std::make_index_sequence<N>());
}


int main()
{
 foo<2, 1,2,3>();
}

但这不是(我使用 foo2 的默认参数):

template <size_t N, size_t... N_i, size_t... M_i>
auto foo2(std::index_sequence<M_i...> = std::make_index_sequence<N>())
{

    constexpr size_t values[] = {N_i...};
    return A<values[M_i]...>();
}


template <size_t N,size_t... N_i>
auto foo()
{
    return foo2<N,N_i...>();
}


int main()
{
 foo<2, 1,2,3>();
}

非常感谢。

鉴于:

template <size_t N, size_t... N_i, size_t... M_i>
auto foo2(std::index_sequence<M_i...> = std::make_index_sequence<N>());

您不能明确指定 M_i(因为序列会作为 N_i 的一部分被吞没)。如果您指定一个参数,那么编译器可以使用模板参数推导来计算出 M_i 是什么。如果您 指定参数,则编译器无法推断出 M_i 是什么(并且它需要知道这一点,然后才能开始决定您需要一个默认值参数,以及该参数是什么)。

假设这是一个较大整体的一小部分,那么解决方法是写

template <size_t N, size_t... N_i, size_t... M_i>
auto foo2(std::index_sequence<M_i...>)
{

    constexpr size_t values[] = {N_i...};
    return A<values[M_i]...>();
}


template <size_t N,size_t... N_i>
auto foo2()
{
    return foo2<N,N_i...>(std::make_index_sequence<N>());
}

那你确实可以这样写:

template <size_t N,size_t... N_i>
auto foo()
{
    return foo2<N,N_i...>();
}