过了一段时间以来,我一直这样做,但这是第一次尝试。 毫无疑问,这是可以改善的。
template<unsigned fixedIndex, class T> class DynamicTupleGetter { typedef typename std::tuple_element<fixedIndex, T>::type RetType; public: static RetType get(unsigned dynIndex, const T& tupleInstance) { const RetType& ret = std::get<fixedIndex>(tupleInstance); if (fixedIndex == dynIndex) return ret; return DynamicTupleGetter<fixedIndex - 1, T>::get(dynIndex, tupleInstance); } }; template<class T> class DynamicTupleGetter<0, T> { typedef typename std::tuple_element<0, T>::type RetType; public: static RetType get(unsigned dynIndex, const T& tupleInstance) { assert(dynIndex == 0); return std::get<0>(tupleInstance); } }; template<class Source> struct Converter { typedef typename std::tuple_element<0, Source>::type Zeroth; typedef typename std::tuple_element<1, Source>::type First; static const size_t size0 = std::tuple_size<Zeroth>::value; static const size_t size1 = std::tuple_size<First>::value; static const size_t outerProductSize = size0 * size1; typedef typename std::tuple_element<0, Zeroth>::type BaseType0; typedef typename std::tuple_element<0, First>::type BaseType1; typedef typename std::tuple<BaseType0, BaseType1> EntryType; typedef std::array<EntryType, outerProductSize> DestinationType; DestinationType create(const Source& source) { Zeroth zeroth = std::get<0>(source); First first = std::get<1>(source); typedef typename DynamicTupleGetter<size0 -1, Zeroth> ZerothGetter; typedef typename DynamicTupleGetter<size1 -1, First> FirstGetter; DestinationType result; size_t resultIndex = 0; for(size_t i = 0; i < size0; ++i) for(size_t j = 0; j < size1; ++j) { std::get<0>(result[resultIndex]) = ZerothGetter::get(i, zeroth) ; std::get<1>(result[resultIndex]) = FirstGetter::get(j, first); ++resultIndex; } return result; } }; template<class T> void create(const T& source) { Converter<T> converter; Converter<T>::DestinationType result = converter.create(source); std::cout << std::get<0>(std::get<3>(result)) << "," << std::get<1>(std::get<3>(result)) << std::endl; } auto intPart = std::make_tuple(2,5,9); auto stringPart = std::make_tuple("foo","bar"); auto source = std::make_tuple(intPart, stringPart); void f() { create(source); }