La mia soluzione non è elegante come quella di Yacc (dopotutto sto cercando di imparare) bu t penso che sia relativamente semplice.
Commenti e segnalazioni di difetti sono i benvenuti.
#include <tuple>
#include <vector>
#include <complex>
#include <iostream>
#include <initializer_list>
template <std::size_t ... N, typename X, typename ... Al>
void cartHelp (std::vector<X> & v,
std::tuple<Al...> const & t)
{ v.emplace_back(std::get<N>(t)...); }
template <std::size_t ... N, typename X, typename ... Al1, typename L,
typename ... Al2>
void cartHelp (std::vector<X> & v,
std::tuple<Al1...> const & t,
std::initializer_list<L> const & l,
std::initializer_list<Al2> const & ... al2)
{
for (auto const & elem : l)
cartHelp<N..., sizeof...(N)>(v, std::tuple_cat(t, std::tie(elem)),
al2...);
}
template <typename X, typename L, typename ... Al>
std::vector<X> cartesian (std::initializer_list<L> const & l,
std::initializer_list<Al> const & ... al)
{
std::vector<X> v;
for (auto const & elem : l)
cartHelp<0>(v, std::tie(elem), al...);
return v;
}
int main()
{
auto v1 = cartesian<int>({1,2});
std::cout << "--- v1.size --- " << v1.size() << "\n";
std::cout << "v1";
for (auto const & elem : v1)
std::cout << '[' << elem << ']';
std::cout << '\n';
auto v2 = cartesian<std::complex<double>>
({1.2,2.3,3.4}, {11.11, 22.22, 33.33});
std::cout << "--- v2.size --- " << v2.size() << "\n";
std::cout << "v2";
for (auto const & elem : v2)
std::cout << '[' << elem << ']';
std::cout << '\n';
auto v3 = cartesian<std::tuple<int, double, std::string>>
({1, 2, 3, 4, 5}, {0.1, 0.2, 0.3, 0.4},
{std::string("aaa"), std::string("bbb"), std::string("ccc")});
std::cout << "--- v3.size --- " << v3.size() << "\n";
std::cout << "v3";
for (auto const & elem : v3)
std::cout << '[' << std::get<0>(elem) << ',' << std::get<1>(elem)
<< ',' << std::get<2>(elem) << ']';
std::cout << '\n';
return 0;
}
uscita:
--- v1.size --- 2
v1[1][2]
--- v2.size --- 9
v2[(1.2,11.11)][(1.2,22.22)][(1.2,33.33)][(2.3,11.11)][(2.3,22.22)][(2.3,33.33)][(3.4,11.11)][(3.4,22.22)][(3.4,33.33)]
--- v3.size --- 60
v3[1,0.1,aaa][1,0.1,bbb][1,0.1,ccc][1,0.2,aaa][1,0.2,bbb][1,0.2,ccc][1,0.3,aaa][1,0.3,bbb][1,0.3,ccc][1,0.4,aaa][1,0.4,bbb][1,0.4,ccc][2,0.1,aaa][2,0.1,bbb][2,0.1,ccc][2,0.2,aaa][2,0.2,bbb][2,0.2,ccc][2,0.3,aaa][2,0.3,bbb][2,0.3,ccc][2,0.4,aaa][2,0.4,bbb][2,0.4,ccc][3,0.1,aaa][3,0.1,bbb][3,0.1,ccc][3,0.2,aaa][3,0.2,bbb][3,0.2,ccc][3,0.3,aaa][3,0.3,bbb][3,0.3,ccc][3,0.4,aaa][3,0.4,bbb][3,0.4,ccc][4,0.1,aaa][4,0.1,bbb][4,0.1,ccc][4,0.2,aaa][4,0.2,bbb][4,0.2,ccc][4,0.3,aaa][4,0.3,bbb][4,0.3,ccc][4,0.4,aaa][4,0.4,bbb][4,0.4,ccc][5,0.1,aaa][5,0.1,bbb][5,0.1,ccc][5,0.2,aaa][5,0.2,bbb][5,0.2,ccc][5,0.3,aaa][5,0.3,bbb][5,0.3,ccc][5,0.4,aaa][5,0.4,bbb][5,0.4,ccc]
Quindi, hai ordinato set (tuple). Vuoi prendere il loro prodotto cartesiano e costruire un oggetto di un determinato tipo da ogni elemento di quel prodotto cartesiano? Cosa vuoi fare con questi oggetti a quel punto? Il tuo paragrafo iniziale menziona 'B', ma non ne parli mai più. Sospetto che possa essere modificato senza cambiare la tua domanda. All'interno di ogni tupla '{2,5,6}' possiamo assumere che tutti i valori siano dello stesso tipo o no? – Yakk
_ "se uso questo costrutto magico per" _ Dovresti incarnare di più con il codice (pseudo) che vuoi usare. Come menzionato nella risposta, mostra almeno il tuo codice di esempio Python. –
@Yakk: ho menzionato 'B' solo per sottolineare che la soluzione dovrebbe funzionare per più di un tipo (fisso). –