Constexpr inicialización de matriz para ordenar contenidos.
Esto es un poco un rompecabezas en lugar de un problema del mundo real, pero me he metido en una situación en la que quiero poder escribir algo que se comporte exactamente como
template<int N>
struct SortMyElements {
int data[N];
template<typename... TT>
SortMyElements(TT... tt) : data{ tt... }
{
std::sort(data, data+N);
}
};
int main() {
SortMyElements<5> se(1,4,2,5,3);
int se_reference[5] = {1,2,3,4,5};
assert(memcmp(se.data, se_reference, sizeof se.data) == 0);
}
excepto que quiero elSortMyElements
constructor para serconstexpr
.
Obviamente esto es posible por reparaciones.N
; por ejemplo, puedo especializarme
template<>
struct SortMyElements<1> {
int data[1];
constexpr SortMyElements(int x) : data{ x } {}
};
template<>
struct SortMyElements<2> {
int data[2];
constexpr SortMyElements(int x, int y) : data{ x>y?y:x, x>y?x:y } {}
};
Pero, ¿cómo generalizo esto en algo que funcione paraalguna N
?
Tenga en cuenta que los elementos de la matriz deben provenir de los valores reales de los argumentos, no de los argumentos de tipo no tipo; mis elementos provienen deconstexpr
Expresiones que, a pesar de ser evaluadas en tiempo de compilación, residen firmemente dentro del "sistema de valores", en lugar del "sistema de tipos". (Por ejemplo,Boost.MPL'ssort
Funciona estrictamente dentro del "sistema de tipos".)
He publicado una "respuesta" de trabajo, pero es demasiado ineficiente para trabajarN > 6
. Me gustaría usar esto con2 < N < 50
o por ahí cerca.
(PS: en realidad, lo que realmente me gustaría hacer es mezclar todos los ceros en una matriz hasta el final de la matriz y empaquetar los valores distintos de cero hacia el frente, lo que podría ser más fácil que la clasificación completa; pero creo que la clasificación es más fácil de describir. Siéntase libre de abordar el problema de "barajar ceros" en lugar de ordenar.)