2013-08-09 15 views
6

Böyle bir yardımcı programı el ile yazmanızdan daha iyi bir çözüm var mı?std :: tuple ile yineleme nasıl yapılır?

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)); 
} 

bu gibi kullanılabilir için:

ihtiyaç üzerine
std::tuple<char, int, double> tt; 
TupleForEach(tt, (boost::lambda::_1 = 5)); 
+1

"Daha iyi" kriterleriniz nelerdir? – Casey

+0

@Casey - "std" veya "boost" da bir kütüphane uygulaması; değilse, o zaman daha az kod içeren bir uygulama; ya da belki bu uygulamada bir sorun var. – Vahagn

cevap

1

bir previous, related question (ve bir kendi verdiğiniz) sağlanan çeşitli cevaplar bulunsa da, benim ilk izlenim yineleme için bu tuple zayıf bir tasarımın yansıması olabilir. Bildiğiniz gibi, std::tuple üzerinden standart C++ algoritmaları kullanarak yineleme yapamamanın nedeni, std::tuple'un Container concept yerine getirilmemesidir. Ve kesin olarak, bu kavramı yerine getirmez, çünkü std::tuple s value_type (heterojen) değildir. Kendi polimorfik tipinizi oluşturmak istemediğiniz ve standart bir kapsayıcıda sakladığınız (örneğin, std::vector<std::shared_ptr<BaseClass>>) bir tuple kullandığınızı biliyorum. Bu size hızlı bir kazanç sağladı. Ama bu aynı zamanda, gönüllü olarak Container s'nin avantajlarından vazgeçtiğiniz anlamına gelir.

Çalışabilir, ancak bir şekilde zorla ve doğal olmayan bir şey hisseder: kapsayıcı semantiğe ihtiyacınız varsa, neden bir kapsayıcı kullanmayın? Polimorfik semantiğe ihtiyacınız varsa, neden bir polimorfik tip kullanmayın?

Muhtemelen abartıyorum, ama bu benim ilk izlenimim.

+0

Muamele türlerinde polimorfik bir temel sınıf yaratmadığımı gösterme sebebi, bir whim :) değil. Bu tipler üçüncü taraflardan, yani bunları kullananlardan kesinlikle emin olanı değil. onlar. Bununla birlikte, bu türler ortak bir kavramı paylaşır, bu nedenle her biri için bazı işlemler geçerlidir, dolayısıyla bu türden nesnelerin bir demetini saklayan kişi, bu nesnelerin bu nesneler üzerinde gerçekleştirilmesini isteyebilir. – Vahagn

+4

Ayrıca, “char”, “int” ve “double” dizilerini düşünün. Ya da bazı işaretçilerden oluşan bir tuple. İlk durumda, örn. tupl elemanlarının sıfır olarak ayarlanması için geçerli bir işlem ve ikinci durumda, örn. tuple üyelerinin 'nullptr' olarak ayarlanması için geçerli bir işlem, ancak C++ 'da tüm aritmetik türler için bir temel sınıf veya tüm işaretçi türleri için bir temel sınıf düşünmek bir tür saçmalıktır. – Vahagn