инициализация массива constexpr для сортировки содержимого
Это скорее загадка, чем проблема реального мира, но я попал в ситуацию, когда хочу написать что-то, что ведет себя точно так же, как
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);
}
кроме того, что я хочуSortMyElements
конструктор бытьconstexpr
.
Очевидно, это возможно для фиксированнойN
; например, я могу специализироваться
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 } {}
};
Но как я могу обобщить это в то, что будет работать дляЛюбые N
?
Обратите внимание, что элементы массива должны исходить из фактических значений аргументов, а не из аргументов не типового шаблона; мои элементы происходят изconstexpr
выражения, которые, несмотря на то, что они оцениваются во время компиляции, находятся в «системе ценностей», а не в «системе типов». (Например,Boost.MPL-хsort
работает строго в рамках "системы типов".)
Я опубликовал рабочий «ответ», но он слишком неэффективен дляN > 6
, Я хотел бы использовать это с2 < N < 50
или около того.
(PS. На самом деле, мне бы очень хотелось переместить все нули в массиве до конца массива и упаковать ненулевые значения в начало, что может быть проще, чем полная сортировка; но я считаю, что сортировка проще описать. Не стесняйтесь решать проблему «перемешать нули» вместо сортировки.)