make_index_sequence如何工作?

时间:2018-05-08 11:48:27

标签: c++

我无法理解代码的这一部分。我知道它会生成一系列数字,来自https://stackoverflow.com/a/24481400/403360 但是我不能用这个做出逻辑,我需要一些指导来完成这个。特别是为什么N-1, N-1

template <size_t ...I>
struct index_sequence {};

template <size_t N, size_t ...I>
struct make_index_sequence : public make_index_sequence<N - 1, N - 1, I...> {};

template <size_t ...I>
struct make_index_sequence<0, I...> : public index_sequence<I...> {};

以及make_index_sequence<sizeof...(T)>()do_foo_helper的影响是什么?它似乎只是传递给没有名字的函数,有些东西会有所帮助。

template<typename ...T, size_t ...I>
/* ... */ do_foo_helper(std::tuple<T...> &ts, index_sequence<I...>) {
    std::tie(foo(std::get<I>(ts)) ...);
}

template <typename ...T>
/* ... */ do_foo(std::tuple<T...> &ts) {
    return do_foo_helper(ts, make_index_sequence<sizeof...(T)>());
}

1 个答案:

答案 0 :(得分:2)

让我们玩编译器,并替换模板参数的值

当它遇到类似std::make_index_sequence<3>的类型时,它会查看模板及其专业化,并与

匹配
template <3>
struct make_index_sequence : public make_index_sequence<2, 2> {};

make_index_sequence<3>的基类是make_index_sequence的另一个实例,所以我们用新参数重复

template <2, 2>
struct make_index_sequence : public make_index_sequence<1, 1, 2> {};

再次

template <1, 1, 2>
struct make_index_sequence : public make_index_sequence<0, 0, 1, 2> {};

现在我们达到专业化

template <0, 1, 2>
struct make_index_sequence<0, 0, 1, 2> : public index_sequence<0, 1, 2> {};

现在我们有一个从index_sequence<0, 1, 2>继承(间接)的类型,因此模板函数可以将参数包绑定到0, 1, 2以匹配传递的参数。

sizeof...(T)只是一个计算参数包T大小的运算符,所以我们有类似的东西:

template <int, bool, char>
/* ... */ do_foo(std::tuple<int, bool, char> & ts)
{
    return do_foo_helper(ts, make_index_sequence<3>());
}

哪个电话

template <int, bool, char, 0, 1, 2>
/* ... */ do_foo_helper(std::tuple<int, bool, char> & ts, std::index_sequence<0, 1, 2>)
{
    std::tie(foo(std::get<0>(ts)), foo(std::get<1>(ts)), foo(std::get<2>(ts)));
}

即。我们只需要第二个参数的类型,而不是它的值(无论如何,类型std::index_sequence<0, 1, 2>只有一个值,它没有数据成员)。