在编译时生成相同类型的std :: tuple,其长度为模板参数

yue*_*ngz 9 c++ template-meta-programming c++11 stdtuple

在c ++中,如何使用指示元组长度的int模板参数实现一个函数并生成一个具有该长度的std :: tuple?

例如

func<2>() returns std::tuple<int, int>();
func<5>() returns std::tuple<int, int, int, int, int>().
Run Code Online (Sandbox Code Playgroud)

rah*_*ma1 14

这是一个带有别名模板的递归解决方案,它可以在C++ 11中实现:

template <size_t I,typename T> 
struct tuple_n{
    template< typename...Args> using type = typename tuple_n<I-1, T>::template type<T, Args...>;
};

template <typename T> 
struct tuple_n<0, T> {
    template<typename...Args> using type = std::tuple<Args...>;   
};
template <size_t I,typename T>  using tuple_of = typename tuple_n<I,T>::template type<>;
Run Code Online (Sandbox Code Playgroud)

例如,如果我们想要,"tuple of 3 doubles"我们可以写:

tuple_of<3, double> t;
Run Code Online (Sandbox Code Playgroud)


Rya*_*ing 8

使用index_sequence和辅助类型别名可以生成所需的类型:

// Just something to take a size_t and give the type `int`
template <std::size_t>
using Integer = int;

// will get a sequence of Is = 0, 1, ..., N
template <std::size_t... Is>
auto func_impl(std::index_sequence<Is...>) {
    // Integer<Is>... becomes one `int` for each element in Is...
    return std::tuple<Integer<Is>...>{};
}

template <std::size_t N>
auto func() {
    return func_impl(std::make_index_sequence<N>{});
}
Run Code Online (Sandbox Code Playgroud)

值得一提的是,在一般情况下你可能会更好用a std::array,(在你的情况下你不能使用),但是a std::array可以表现得像元组,类似于a std::pair.

更新:既然你已经明确表示你正在使用c ++ 11而不是14+,你需要index_sequence从某个地方获得一个实现和相关的(这里是libc ++).这是C++ 11版本funcfunc_impl具有显式返回类型:

template <std::size_t... Is>
auto func_impl(std::index_sequence<Is...>) -> std::tuple<Integer<Is>...> {
  return std::tuple<Integer<Is>...>{};
}

template <std::size_t N>
auto func() -> decltype(func_impl(std::make_index_sequence<N>{})) {
  return func_impl(std::make_index_sequence<N>{});
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这是C++ 14. (2认同)

eer*_*ika 5

普通的旧递归是你的朋友:

template<std::size_t N>
auto array_tuple() {
    return std::tuple_cat(std::tuple<int>{}, array_tuple<N-1>());
}

template<>
auto array_tuple<0>() {
    return std::tuple<>{};
}
Run Code Online (Sandbox Code Playgroud)