Voici une implémentation plutôt simple et ennuyeuse.
#include <cstdlib>
#include <iostream>
namespace ct {
template <typename, typename>
struct pair {};
template <typename... a>
struct list {};
template <typename a, typename... b>
struct cons_t;
template <typename a>
struct cons_t<a, list<>>
{
using type = list<a>;
};
template <typename a, typename bh, typename... bt>
struct cons_t<a, list<bh, bt...>>
{
using type = list<a, bh, bt...>;
};
template <typename a, typename... b>
struct concat_t;
template <typename b>
struct concat_t<list<>, b>
{
using type = b;
};
template <typename b, typename ah, typename... at>
struct concat_t<list<ah, at...>, b>
{
using type = typename cons_t<ah, typename concat_t<list<at...>, b>::type>::type;
};
template <typename a, typename b>
using cons = typename cons_t<a,b>::type;
template <typename a, typename b>
using concat = typename concat_t<a,b>::type;
template <typename a, typename b>
struct cartesian1;
template <typename a>
struct cartesian1<a, list<>>
{
using type = list<>;
};
template <typename a, typename bh, typename... bt>
struct cartesian1<a, list<bh, bt...>>
{
using type = cons<pair<a, bh>, typename cartesian1<a, list<bt...>>::type>;
};
template <typename a, typename b>
struct cartesian_t;
template <typename a>
struct cartesian_t<list<>, a>
{
using type = list<>;
};
template <typename ah, typename b, typename... at>
struct cartesian_t<list<ah, at...>, b>
{
using type = concat<typename cartesian1<ah, b>::type,
typename cartesian_t<list<at...>, b>::type>;
};
template <typename a, typename b>
using cartesian = typename cartesian_t<a,b>::type;
template <size_t x>
struct val {};
template <size_t... a>
struct vlist {};
template <typename t>
struct vlist2list_t;
template <>
struct vlist2list_t<vlist<>>
{
using type = list<>;
};
template <size_t ah, size_t... at>
struct vlist2list_t<vlist<ah, at...>>
{
using type = cons<val<ah>, typename vlist2list_t<vlist<at...>>::type>;
};
template <typename a>
using vlist2list = typename vlist2list_t<a>::type;
template <size_t...a>
using vl = vlist2list<vlist<a...>>;
template<size_t x1, size_t x2>
std::ostream& operator<< (std::ostream& s,
pair<val<x1>, val<x2>> z)
{
s << "(" << x1 << "," << x2 << ")";
return s;
}
std::ostream& operator<< (std::ostream& s,
list<> z)
{
s << "[]";
}
template <typename ah, typename... at>
std::ostream& operator<< (std::ostream& s,
list<ah, at...> z)
{
s << ah() << ":" << list<at...>();
}
}
int main()
{
using a = ct::cartesian<ct::vl<1,2,3>, ct::vl<4,5,6>>;
std::cout << a() << std::endl;
}
Comment vous attendez-vous à ce que la séquence finale ressemble? Une liste de paires d'indices? Aussi, tout ce que vous avez déjà essayé? Vous devriez juste être capable de regarder comment un produit cartésien est fait pour les vecteurs/listes normaux et le transférer à TMP. – Xeo
J'ai quitté la représentation des paires ouvertes, il pourrait être n'importe quoi, ils pourraient être «aplati» dans une seule séquence de taille égale. Je vais essayer plus tard dans la journée, ne devrait pas être trop dur, mais je pensais que quelqu'un pourrait simplement copier et coller du code écrit il ya longtemps :) – user1095108