以下代码定义了函数subst_first,该函数将int数组的第一个元素替换为另一个数组的内容。它在gcc和clang(live demo)下工作。对于//1//2//3而言,生成的 index_sequence 's之一为空。因此,位于//4的参数包之一具有零个元素。这让我感到不安。我可以依靠这种行为来符合标准吗?

template<size_t n, size_t ... S1, size_t ... S2>
constexpr
std::array<int,3>
subst_first_impl( std::array<int,n> const &v1,
                  std::array<int,3> const &v2,
                  size_t min_n,
                  std::index_sequence<S1...>,
                  std::index_sequence<S2...> )
{    return std::array<int,3>{{ v1[S1]..., v2[min_n+S2]... }}; } // 4

template<size_t n>
constexpr
std::array<int,3>
subst_first( std::array<int,n> const &v1,
             std::array<int,3> const &v2 )
{   auto const min_n= std::min( size_t(3), n );
    return subst_first_impl( v1, v2, min_n,
                             std::make_index_sequence< min_n >(),
                             std::make_index_sequence< size_t(3) - min_n >() );
}

int main(){
    constexpr std::array<int,3>  a1{{1,2,3}};

    constexpr std::array<int,2>  b1{{4,5}};
    constexpr std::array<int,3>  b2{{6,7,8}};
    constexpr std::array<int,4>  b3{{9,10,11,12}};
    constexpr std::array<int,0>  b4{};

    constexpr auto b1a1= subst_first( b1, a1 );
    // ==> 4, 5, 3

    constexpr auto b2a1= subst_first( b2, a1 ); // 1
    // ==> 6, 7, 8

    constexpr auto b3a1= subst_first( b3, a1 ); // 2
    // ==> 9, 10, 11

    constexpr auto b4a1= subst_first( b4, a1 ); // 3
    // ==> 1, 2, 3
}

注意:我不是在寻找替代数组元素的解决方案。我对index_sequence和参数包的行为感兴趣。

最佳答案

首先,std::make_index_sequence<0>完全有效(第20.5.3节[intseq.make]):

因此,在您的情况下,您会得到一个std::index_sequence<size_t>
根据§14.5.3/ 7 [temp.variadic],长度为0的包展开的实例完全正确:

关于c++ - 我可以依靠空的参数包来正确扩展吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38146184/

10-13 08:06