【问题标题】:C++: Creating a variable length tuple based on integral template parameterC ++:基于整数模板参数创建可变长度元组
【发布时间】:2018-01-16 16:45:13
【问题描述】:

我正在编写一个库,它具有以无符号整数为模板的编译时多态对象,

template<unsigned level> class Foo { ... };

,即 Foo、Foo、Foo 等,直到每个应用程序确定的特定数量。假设我们的应用程序指定需要数字 0、1、...、n。

我需要能够构造一个指向这些对象的指针向量元组:std::tuple&lt;std::vector&lt;Foo&lt;n&gt; *&gt;, std::vector&lt;Foo&lt;n-1&gt; *&gt;, ..., vector&lt;Foo&lt;0&gt; *&gt;&gt; 通过调用可变参数模板函数,示意性地:

template <unsigned n> 
std::tuple<unsigned n, unsigned... Args> create_vector_tuple<n>()

或类似的东西。

我的直觉告诉我,这应该是可以实现的,尽管我在这里的深度不够。

如果有人能指出实现这一点的方法,我将不胜感激!

【问题讨论】:

标签: c++ c++14 variadic-templates template-meta-programming


【解决方案1】:

类似于以下内容:

#include <cstdio>
#include <tuple>
#include <vector>
#include <utility>

template<unsigned level> struct Foo {};

template<unsigned N, unsigned... Ns>
std::tuple<std::vector<Foo<N - Ns>*>...> create_vector_tuple_imp(std::integer_sequence<unsigned, Ns...>) {
    return {};
}

template <unsigned n>
auto create_vector_tuple() {
    return create_vector_tuple_imp<n>(std::make_integer_sequence<unsigned, n>{});
}

template<class T>
void print() {
    std::printf("%s\n", __PRETTY_FUNCTION__);
}

int main() {
    auto t = create_vector_tuple<10>();
    print<decltype(t)>();
}

输出:

void print() [with T = std::tuple<std::vector<Foo<10u>*, std::allocator<Foo<10u>*> >, std::vector<Foo<9u>*, std::allocator<Foo<9u>*> >, std::vector<Foo<8u>*, std::allocator<Foo<8u>*> >, std::vector<Foo<7u>*, std::allocator<Foo<7u>*> >, std::vector<Foo<6u>*, std::allocator<Foo<6u>*> >, std::vector<Foo<5u>*, std::allocator<Foo<5u>*> >, std::vector<Foo<4u>*, std::allocator<Foo<4u>*> >, std::vector<Foo<3u>*, std::allocator<Foo<3u>*> >, std::vector<Foo<2u>*, std::allocator<Foo<2u>*> >, std::vector<Foo<1u>*, std::allocator<Foo<1u>*> > >]

【讨论】:

  • 请注意,这需要 C++14 支持 std::make_integer_sequenceauto 而没有尾随返回类型。 std::make_integer_sequence 可以反向移植到 C++11,如有必要,将声明更改为 auto create_vector_tuple() -&gt; decltype(create_vector_tuple_imp&lt;n&gt;(std::make_integer_sequence&lt;unsigned, n&gt;{})) 以添加尾随返回类型。
  • 非常感谢!尚未测试您的建议,但自发地它看起来正是我正在寻找的。我用 C++14 编写,所以没问题(选择标记 C++11 作为比 C++14 更宽的保护伞)。
  • 很好,但是...你确定std::make_integer_sequence&lt;unsigned, n&gt; 吗?还是应该是std::make_integer_sequence&lt;unsigned, n+1U&gt;
  • @max66 你是对的,如果那里需要Foo&lt;0&gt;,那么它应该是std::make_integer_sequence&lt;unsigned, n + 1&gt;{}
猜你喜欢
  • 2022-09-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-25
  • 2017-09-03
相关资源
最近更新 更多