如何遍历std :: tuple?

Vah*_*agn 6 c++ foreach tuples template-meta-programming c++11

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

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 ) );
}
Run Code Online (Sandbox Code Playgroud)

要像这样使用:

std::tuple<char, int, double> tt;
TupleForEach( tt, (boost::lambda::_1 = 5) );
Run Code Online (Sandbox Code Playgroud)

Esc*_*alo 1

尽管在之前的相关问题(以及您自己提供的问题)中提供了多个答案,但我的第一印象是迭代元组的需要可能反映了糟糕的设计。

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

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

可能我有点夸张,但这是我的初步印象。

  • 此外,考虑一个“char”、“int”和“double”的元组。或者一些指针的元组。在第一种情况下,有一个将元组成员设置为零的有效操作,在第二种情况下,有一个将元组成员设置为“nullptr”的有效操作,但在 C++ 中,这肯定是一种无意义的操作。考虑所有算术类型的基类或所有指针类型的基类。 (4认同)