这是一个很丑陋的做法,可能不是在常量表达式中排序的最佳方式(由于需要实例化深度),但是有了归并排序:
帮助类型,具有可返回的数组类型和constexpr元素访问:
#include <cstddef>
#include <iterator>
#include <type_traits>
template<class T, std::size_t N>
struct c_array
{
T arr[N];
constexpr T const& operator[](std::size_t p) const
{ return arr[p]; }
constexpr T const* begin() const
{ return arr+0; }
constexpr T const* end() const
{ return arr+N; }
};
template<class T>
struct c_array<T, 0> {};
append
函数用于该数组类型:
template<std::size_t... Is>
struct seq {};
template<std::size_t N, std::size_t... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...> {};
template<std::size_t... Is>
struct gen_seq<0, Is...> : seq<Is...> {};
template<class T, std::size_t N, class U, std::size_t... Is>
constexpr c_array<T, N+1> append_impl(c_array<T, N> const& p, U const& e,
seq<Is...>)
{
return {{p[Is]..., e}};
}
template<class T, std::size_t N, class U>
constexpr c_array<T, N+1> append(c_array<T, N> const& p, U const& e)
{
return append_impl(p, e, gen_seq<N>{});
}
归并排序:
template<std::size_t Res, class T, class It, std::size_t Accum,
class = typename std::enable_if<Res!=Accum, void>::type >
constexpr c_array<T, Res> c_merge(It beg0, It end0, It beg1, It end1,
c_array<T, Accum> const& accum)
template<std::size_t Res, class T, class It, class... Dummies>
constexpr c_array<T, Res> c_merge(It beg0, It end0, It beg1, It end1,
c_array<T, Res> const& accum, Dummies...)
template<class T, std::size_t L, std::size_t R>
constexpr c_array<T, L+R> c_merge(c_array<T, L> const& l,
c_array<T, R> const& r)
);
}
template<class T>
using rem_ref = typename std::remove_reference<T>::type;
template<std::size_t dist>
struct helper
};
template<>
struct helper<0>
;
}
};
template<>
struct helper<1>
;
}
};
template < std::size_t dist, class It >
constexpr auto merge_sort(It beg, It end)
-> c_array<rem_ref<decltype
使用示例的辅助工具:
template<class T, std::size_t N>
constexpr std::size_t array_size(T (&arr)[N])
template<class T, std::size_t N>
constexpr T* c_begin(T (&arr)[N])
template<class T, std::size_t N>
constexpr T* c_end(T (&arr)[N])
使用示例:
constexpr int unsorted[] = {5,7,3,4,1,8,2,9,0,6,10};
constexpr auto sorted = merge_sort<array_size(unsorted)>(c_begin(unsorted),
c_end(unsorted));
#include <iostream>
int main()
{
std::cout << "unsorted: ";
for(auto const& e : unsorted) std::cout << e << ", ";
std::cout << '\n';
std::cout << "sorted: ";
for(auto const& e : sorted) std::cout << e << ", ";
std::cout << '\n';
}
输出:
未排序: 5, 7, 3, 4, 1, 8, 2, 9, 0, 6, 10,
已排序: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
constexpr
(比如你的构造函数)中调用非constexpr
函数(比如sort)吗?这样做似乎没有什么意义。 - masaersstd::sort
不是 constexpr;这个谜题是要编写一个像std::sort
一样的东西,但 是 constexpr 的。 - Quuxplusone