【问题标题】:How to iterate through std::tuple? [duplicate]如何遍历 std::tuple? [复制]
【发布时间】:2013-08-11 21:47:06
【问题描述】:

有比手动编写这样的实用程序更好的解决方案吗?

template < size_t > struct SizeT { };

template < typename TupleType, typename ActionType >
inline void TupleForEach( TupleType& tuple, ActionType action )
{
    TupleForEach( tuple, action, SizeT<std::tuple_size<TupleType>::value>() );
}

template < typename TupleType, typename ActionType >
inline void TupleForEach( TupleType& tuple, ActionType action, SizeT<0> ) { }

template < typename TupleType, typename ActionType, size_t N >
inline void TupleForEach( TupleType& tuple, ActionType action, SizeT<N> )
{
    TupleForEach( tuple, action, SizeT<N-1>() );
    action( std::get<N-1>( tuple ) );
}

这样使用:

std::tuple<char, int, double> tt;
TupleForEach( tt, (boost::lambda::_1 = 5) );

【问题讨论】:

  • 你对“更好”的标准是什么?
  • @Casey -- stdboost 中的库实现;如果没有,那么代码更少的实现;或者这个实现中可能存在问题。

标签: c++ c++11 foreach tuples template-meta-programming


【解决方案1】:

尽管previous, related question 中提供了多个答案(以及您自己提供的答案),但我最初的印象是,需要迭代元组可能反映了糟糕的设计。

如您所知,我们不能使用标准 C++ 算法迭代 std::tuple 的原因是因为 std::tuple 不满足 Container concept。而且,准确地说,它不满足这样的概念,因为std::tuples 没有value_type(它们是异构的)。我知道您使用元组是因为您不想创建自己的多态类型并将其存储在标准容器中(例如,std::vector&lt;std::shared_ptr&lt;BaseClass&gt;&gt;)。这给了你一个快速的收获。但这也意味着你自愿放弃了Containers的优势。

它可能有效,但不知何故让人觉得强迫和不自然:如果您需要容器语义,为什么不使用容器呢?如果你需要多态语义,为什么不使用多态类型呢?

可能我夸大了,但这是我最初的印象。

【讨论】:

  • 我没有为元组中的类型创建多态基类的原因并不是一时兴起 :) 这些类型来自第三方,所以肯定是谁使用它们,不一定是维护它们的人。然而,这些类型有一个共同的概念,因此某些操作对它们中的每一个都有效,因此存储这些类型的一堆对象的人可能希望对这些对象执行此类操作。
  • 此外,考虑 charintdouble 的元组。或者一些指针的元组。在第一种情况下,例如将元组成员设置为零的有效操作,在第二种情况下,例如将元组成员设置为nullptr 的有效操作,但可以肯定的是,在 C++ 中,考虑所有算术类型的基类或所有指针类型的基类是一种废话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-22
  • 1970-01-01
  • 2017-12-10
  • 2020-06-11
  • 1970-01-01
  • 2017-10-10
  • 2012-11-12
相关资源
最近更新 更多