【问题标题】:c++ : convert vector to tuplec++:将向量转换为元组
【发布时间】:2023-04-07 19:25:01
【问题描述】:

如何将 std::vector 转换为 std::tuple ? 我有

class T { };
int cnt = 3;
vector<T*> tv;
for (int i = 0; i < cnt; ++i) {
  tv.push_back(new T());
}

我想得到

auto tp = std::tie(*tv[0], *tv[1], *tv[2]);

我怎样才能得到这个 tp ? 如果cnt足够大,我不能手动写这个tp。

  std::vector<
  ConvConnection<
  decltype(inputLayer),
  decltype(*C1[0]),
  decltype(*Conn1Opt[0]),
  RandomInitialization<arma::mat>,
  arma::mat
  >* > Conn1(6);

  for (size_t i = 0; i < 6; ++i) {
    Conn1.push_back(new  ConvConnection<
                    decltype(inputLayer),
                    decltype(*C1[0]),
                    decltype(*Conn1Opt[0]),
                    RandomInitialization<arma::mat>,
                    arma::mat
                    >(inputLayer, *C1[i], *Conn1Opt[i], 5, 5));
  }

这是代码。这里只有 6 个,但我还需要一些大小超过 100 的向量。我需要将此向量转换为元组。

【问题讨论】:

  • 如果手动编写太大或太麻烦,请编写另一个程序生成它。如果你想在运行时确定元组的大小,你不能。
  • 为什么需要一个元组? std::array&lt;T*,MAX&gt; 不行吗?
  • 一个离题的挑剔:你真的应该有更好的变量/类名。没有理由cnt 不能写成count。什么是ConvConnectionConn1Opt?在 2015 年,您的源文件仍然可以放入您的硬盘驱动器中,其中包含一些额外的字符,其他查看您的代码的开发人员稍后会感谢您:)

标签: c++ c++11 tuples


【解决方案1】:

通常,您无法将 vector 转换为 tuple。但是,如果您要做的只是为某些 N 生成元组 &lt;f(0), f(1), ..., f(N-1)&gt;,这是一个常量表达式,那么使用索引序列技巧是可行的:

template <typename F, size_t... Is>
auto gen_tuple_impl(F func, std::index_sequence<Is...> ) {
    return std::make_tuple(func(Is)...);
}

template <size_t N, typename F>
auto gen_tuple(F func) {
    return gen_tuple_impl(func, std::make_index_sequence<N>{} );
}

我们可以这样使用:

// make a tuple of the first 10 squares: 0, 1, 4, ..., 81
auto squares = gen_tuple<10>([](size_t i){ return i*i;});

对于您的特定用例,这将是:

auto connections = gen_tuple<6>([&](size_t i) {
    return new ConvConnection<
                decltype(inputLayer),
                decltype(*C1[0]),
                decltype(*Conn1Opt[0]),
                RandomInitialization<arma::mat>,
                arma::mat
                >(inputLayer, *C1[i], *Conn1Opt[i], 5, 5);
});

【讨论】:

  • 谢谢。但是我需要元组 ,其中每个 Ti 都是一个类。我用它来建立一个神经元网络。因为当前的神经网络框架使用元组,但是现在我的网络太大了,我可以手动编写它。看来我必须更改框架或使用另一个程序生成它。
  • @HurricaneTong 你也可以通过类来做到这一点。只需将make_tuple(Is...) 替换为make_tuple(new T(Is)...)
  • 我更新了问题并给出了我的真实代码。元组中的每个类都有不同的构造参数。你能帮我解决这个问题吗?
  • @JaraxussTong 更新了我的答案以允许您可以传入一个函数。
【解决方案2】:

如果你有 C++14,你可以这样做:

template <typename T, std::size_t... Indices>
auto vectorToTupleHelper(const std::vector<T>& v, std::index_sequence<Indices...>) {
  return std::make_tuple(v[Indices]...);
}

template <std::size_t N, typename T>
auto vectorToTuple(const std::vector<T>& v) {
  assert(v.size() >= N);
  return vectorToTupleHelper(v, std::make_index_sequence<N>());
}

多亏了自动扣除,这没问题。在 C++11 中,如果没有自动推导,则必须编写带有尾随 decltype 的返回类型。您还必须实现自己的index_sequence

【讨论】:

  • 我知道这是一个相当老的问题,但是如何在没有自动推导但支持 c++17 的情况下编写模板参数?
  • 恐怕我不知道 - 我没有跟上 C++ post-14。
【解决方案3】:

你就是做不到。因为向量大小在运行时是已知的,但tuple 类型(包括它的大小)必须在编译时知道。

【讨论】:

  • 那我怎样才能得到一个“大”元组呢?我想得到 auto tp = std::tie(T1, T2, T3, ..... TN) 假设 N 足够大,我必须生成 T1 ... TN 动态。假设我写代码时 N 是固定的。
  • 什么是“大”元组?
猜你喜欢
  • 2015-01-25
  • 2020-12-08
  • 2015-09-08
  • 1970-01-01
  • 2017-10-10
  • 2019-07-17
  • 2011-01-06
  • 2011-09-17
  • 1970-01-01
相关资源
最近更新 更多