IBR*_*RIT 2 c++ sfinae c++17 c++20
我实现了编译时检查,以检查是否使用下面给出的代码对某些内容进行了排序:
template<typename IntegerSequence>
struct is_sorted {
static constexpr bool value = true;
};
template<typename Integer, Integer Head, Integer Next, Integer... Tail>
struct is_sorted<std::integer_sequence<Integer, Head, Next, Tail...>> {
static constexpr bool value = Head <= Next && is_sorted<std::integer_sequence<Integer, Next, Tail...>>::value;
};
Run Code Online (Sandbox Code Playgroud)
上面的代码有效。我计划使用这些排序检查创建两个额外的元函数,这将生成没有重复的新序列
using in_seq = std::integer_sequence<int, 1,2,3,4>;
using mod_seq = is_sorted<in_seq>::value ? remove_duplicates<in_seq>::uniq_seq : in_seq;
// Examples
// in_seq = 1,2,3,4 -> mod_seq = 1,2,3,4
// in_seq = 1,2,2,3,4 -> mod_seq = 1,2,3,4
Run Code Online (Sandbox Code Playgroud)
如何在编译时使用模板从整数序列中删除重复项。另外,在执行排序检查时是否可以删除重复项,在这种情况下,如果模板检测到序列未排序就停止删除重复项,我就可以了。
// partial sort example 4,4,4,5,5,3,2,2,1 -> 4,5,3,2,2,1 (not sure if this is possible, but just curious)
Run Code Online (Sandbox Code Playgroud)
我不确定如何通过std::integer_sequence动态生成新内容来进行操作。
由于所有 std 算法现在都constexpr在 C++20 中,我们可以使用它以自然方式进行编译时编程(就像@cigien说的那样):
template <typename T, T... Ints>
constexpr auto unique_until_nonsorted(std::integer_sequence<T, Ints...>) {
// constexpr structured bindings are not allow :(
constexpr auto pair = [] {
std::array<T, sizeof...(Ints)> arr{Ints...};
// get last iterator of unique
auto sorted_end = std::is_sorted_until(arr.begin(), arr.end());
// unique until last iterator
auto unique_end = std::unique(arr.begin(), sorted_end);
// copy nonsorted elements to last iterator
auto copy_end = std::copy(sorted_end, arr.end(), unique_end);
// get final arr size
auto size = std::distance(arr.begin(), copy_end);
return std::pair{arr, size};
}();
constexpr auto arr = pair.first;
constexpr auto size = pair.second;
// using template lambda to expand pack
return [&arr]<std::size_t... Is>(std::index_sequence<Is...>) {
return std::integer_sequence<T, arr[Is]...>{};
}(std::make_index_sequence<size>{});
}
Run Code Online (Sandbox Code Playgroud)
template <typename X, X... Xs, typename Y, Y... Ys>
constexpr bool operator==(std::integer_sequence<X, Xs...>,
std::integer_sequence<Y, Ys...>) noexcept {
return ((Xs == Ys) && ...);
}
static_assert(unique_until_nonsorted(std::index_sequence<4,4,4,5,5,3,2,2,1>{}) ==
std::index_sequence<4,5,3,2,2,1>{});
static_assert(unique_until_nonsorted(std::index_sequence<1,2,3,4>{}) ==
std::index_sequence<1,2,3,4>{});
static_assert(unique_until_nonsorted(std::index_sequence<1,2,2,3,4>{}) ==
std::index_sequence<1,2,3,4>{});
static_assert(unique_until_nonsorted(std::index_sequence<2,2,2,2,4,1,1>{}) ==
std::index_sequence<2,4,1,1>{});
static_assert(unique_until_nonsorted(std::index_sequence<1,1,1,2,3,2,2>{}) ==
std::index_sequence<1,2,3,2,2>{});
// corner case
static_assert(unique_until_nonsorted(std::index_sequence<>{}) ==
std::index_sequence<>{});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
519 次 |
| 最近记录: |