constexpr inicjalizacja tablicy do sortowania zawartości
To trochę zagadka, a nie rzeczywisty problem, ale wpadłem w sytuację, w której chcę móc napisać coś, co zachowuje się dokładnie tak
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);
}
poza tym, że chcęSortMyElements
być konstruktoremconstexpr
.
Oczywiście jest to możliwe do naprawieniaN
; na przykład mogę się specjalizować
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 } {}
};
Ale jak uogólnić to na coś, co będzie działaćkażdy N
?
Zauważ, że elementy tablicy muszą pochodzić z rzeczywistych wartości argumentów, a nie z argumentów nietypowych szablonu; moje elementy pochodząconstexpr
wyrażenia, które mimo że są oceniane w czasie kompilacji, znajdują się zdecydowanie w „systemie wartości”, a nie w „systemie typów”. (Na przykład,Boost.MPL'ssort
działa ściśle w „systemie typów”.)
Wysłałem działającą „odpowiedź”, ale jest ona zbyt nieefektywna, aby nad nią pracowaćN > 6
. Chciałbym to wykorzystać2 < N < 50
lub w okolicy.
(PS - Właściwie to, co naprawdę chciałbym zrobić, to przetasować wszystkie zera w tablicy na koniec tablicy i spakować wartości niezerowe w przód, co może być łatwiejsze niż sortowanie w trybie pełnoekranowym; łatwiejsze do opisania, zamiast sortowania, możesz poradzić sobie z problemem „losowych zer”.)