Desidero creare un array 2D popolato da alcune funzioni note con senza sovraccarico di runtime.Inizializzazione di un array 2D semplice con una determinata funzione in fase di compilazione
Per avere un esempio, supponiamo che una funzione f(x, y) = 10 * y + x
, cerchiamo x
essere in {1, 2, 3}
e y
in {4, 5, 6}
. Voglio creare una matrice 2D con contenuti
41 42 43
51 52 53
61 62 63
Ora, il modo più semplice per andare è solo hard-code i valori direttamente nelle mie fonti. Ed è davvero appropriato per il mio compito, quindi la domanda è solo per curiosità.
Vorrei creare un metafunc e una struttura possedere una sorta di magia nera, che mi consente di definire una matrice di determinati set di valori per x
e . Come questo:
template<int X> struct Func {
template<int Y> struct over {
static const int value = 10 * Y + X; // f(x, y)
};
};
template<int... args1> struct Rows {
template<int... args2> struct Cols {
static const int data[sizeof...(args1)][sizeof...(args2)];
};
};
template<int... args1>
template<int... args2>
const int Rows<args1...>::Cols<args2...>::data[sizeof...(args1)][sizeof...(args2)] = {
{ Func<args1>::over<args2>::value... } // This does not do what I want :(
// Need some black magic here
};
// Here is my precious table
const auto& table = Rows<1, 2, 3>::Cols<4, 5, 6>::data;
se stampo valori dalla tabella, ho questo:
41 52 63
0 0 0
0 0 0
ho capito quello che sta succedendo, il termine Func<args1>::over<args2>::value
ha due confezioni di parametri in esso, args1
e args2
, così l'applicazione ...
su di esso espanderli contemporaneamente, e ho solo 3 membri invece di 9.
Se hai raggiunto così lontano, hai già capito quello che voglio. Quindi la domanda è: come faccio? Come applicare i puntini di sospensione separatamente a entrambi i pacchetti di parametri in modo che possa avere una combinazione cartesiana nell'inizializzatore? O forse ci sono altri modi per farlo?
Sono a conoscenza di this answer e that answer. Utilizzano std::array
invece di un semplice array, quindi prima costruiscono array 1D e quindi inizializzano l'array 2D con un numero di array 1D. Ma se ho capito bene, questa inizializzazione deve essere eseguita in runtime. Voglio evitarlo. Tuttavia, non ho obiezioni contro std::array
. Suppongo che con un compilatore appropriato siano veloci quanto semplici array.
A proposito, ecco il mio possible solution utilizzando il constexpr
generalizzato da C++ 14 e una domanda a riguardo. Anche le idee su come risolvere l'attività con constexpr
da C++ 11 sono benvenute.
iterare tutta la riga prima, e poi scorrere attraverso colonne. – VermillionAzure
Sono assolutamente orribile, ma il modo in cui è scritto in questo momento è "ambiguo". La struttura è nidificata, ma non ha l'iterazione template annidata. Quindi magari provare ad avere il tipo specificato per la struct di primo livello e poi farne un altro con il secondo livello strict ancora con un elenco variadic. Quindi creare un'istanza di un caso specifico con il caso istanziato di livello superiore. – VermillionAzure
Hai davvero bisogno di un array 2d?Hai appena trovato la soluzione per un array 1d –