Dies ist ein bisschen wie ein Puzzle, statt einer realen Problem, aber ich habe in eine Situation geraten, wo ich in der Lage sein, etwas zu schreiben, das genau verhält sich wieconstexpr Initialisierung von Array zu sortieren Inhalt
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);
}
außer dass ich möchte, dass der SortMyElements
Konstruktor constexpr
ist.
Offensichtlich ist dies für feste N
möglich; zum Beispiel kann ich
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 } {}
};
spezialisiert Aber wie verallgemeinern ich dies in etwas, das für jedeN
funktionieren wird?
Bitte beachten Sie, dass die Array-Elemente von den tatsächlichen Werten der Argumente kommen, nicht aus Vorlage nicht-Typargument; Meine Elemente stammen aus constexpr
Ausdrücken, die, obwohl sie zur Kompilierungszeit ausgewertet werden, fest im "Wertesystem" und nicht im "Typensystem" verankert sind. (Zum Beispiel Boost.MPL's sort
arbeitet streng innerhalb des „Typ-Systems“).
Ich habe eine funktionierende „Antwort“ geschrieben, aber es ist zu ineffizient für N > 6
zu arbeiten. Ich möchte das mit 2 < N < 50
oder in der Nähe verwenden.
(PS- Eigentlich möchte ich wirklich alle Nullen in einem Array an das Ende des Arrays mischen und die Werte ungleich Null nach vorne packen, was einfacher sein kann als vollständige Sortierung; aber Ich denke, Sortierung ist einfacher zu beschreiben.Fühlen Sie sich frei, die "Shuffle Nullen" Problem statt Sortieren.
Können Sie wirklich nennen Nicht-'constexpr' Funktionen (wie Art) von etwas, das ein 'constexpr' (wie Ihr Konstruktor) ist? Es macht nicht wirklich Sinn, das zu können. – masaers
@masaers Nun, offensichtlich 'std :: sort' ist nicht constexpr; Das Puzzle besteht darin, etwas zu schreiben, das sich wie "std :: sort" verhält, aber * ist * constexpr. – Quuxplusone
Ich sehe, sorry. Eine Kompilierungs-Sortier-Metafunktion wäre ziemlich cool ... – masaers