自定义is_sorted函数模板
Custom is_sorted function template
我想编写自己的is_sorted函数模板实现,而不是使用std::is_sorted。你能告诉我怎么做吗?我只想在数组中使用它。所以我想做这样的声明:
template <typename T, size_t N>
bool is_sorted (const T (&array)[N]); and
bool operator>(const A &, const A &); is declared.
显而易见的方法是将每一项与它后面的项进行比较,看看它是否与那一项<=
你可能不想直接这么做。首先,对于排序,客户端通常只需要确保定义了a < b
,因此您希望使用<
而不是<=
。其次,您希望允许(但不要求)用户传递他们自己的比较器,以防<
没有直接为某些类型定义,或者所需的排序使用与<
定义的不同的标准。
因此,您可能希望定义两个版本的is_sorted
,一个直接使用<
,另一个使用用户传递的比较器。
#include <iterator>
#include <functional>
template <class InIt>
bool is_sorted(InIt b, InIt e) {
if (b == e) // No items -- sorted by definition
return true;
typename std::iterator_traits<InIt>::value_type first = *b;
++b;
while (b != e) { // skip if e-b == 1 (single item is sorted)
if (*b < first)
return false;
first = *b;
++b;
}
return true;
}
template <class InIt, class Cmp>
bool is_sorted(InIt b, InIt e, Cmp cmp) {
if (b == e)
return true;
typename std::iterator_traits<InIt>::value_type first = *b;
++b;
while (b != e) { // skip if e-b == 1 (single item is sorte)
if (cmp(*b, first))
return false;
first = *b;
++b;
}
return true;
}
为了保持我自己的诚实,一点测试代码,与排序,未排序,相同和反向的元素,使用std::vector
, std::deque
, std::array
,和一个内置数组:
#ifdef TEST
#include <array>
#include <vector>
#include <iostream>
#include <deque>
int main() {
std::vector<int> sorted{1, 2, 3, 4, 6, 100};
std::deque<int> unsorted{1, 5, 2, 7, 4};
std::array<int, 7> ident = {1, 1, 1, 1, 1, 3, 3};
int rev[] = {5, 4, 3, 2, 1};
if (!is_sorted(std::begin(sorted), std::end(sorted)))
std::cout << "Sorted array detected as un-sortedn";
if (is_sorted(std::begin(unsorted), std::end(unsorted)))
std::cout << "Un-sorted array detected as sortedn";
if (!is_sorted(std::begin(ident), std::end(ident)))
std::cout << "sorted array with duplicated detected as un-sortedn";
if (!is_sorted(std::begin(rev), std::end(rev), std::greater<int>()))
std::cout << "Reverse sorted array detected as un-sortedn";
return 0;
}
#endif
这在gcc 4.7.2中工作得很好。is_sorted
代码似乎可以很好地与vc++ 2012一起工作(尽管测试代码需要一些小的修改,例如,消除统一初始化的使用,它还不支持)。
编辑:如果你不介意对迭代器有更严格的要求(向前迭代器而不是输入迭代器),你可以使代码更简单,通常更有效。例如,代码可以简化成这样:
template <class FwdIt>
bool is_sorted(FwdIt b, FwdIt e) {
if (b == e) // No items -- sorted by definition
return true;
for (FwdIt first = b; ++b != e; first = b)
if (*b < *first)
return false;
return true;
}
确保容器中的每个元素都是<=
下一个元素。
如果您只有<
比较器(像大多数STL算法一样),请确保容器中没有给定元素是<
前一个元素的元素。
相关文章:
- 当函数模板参数是具有默认参数的类模板时,函数模板参数的推导如何执行
- 将重载的成员函数传递给函数模板
- C++17中函数模板中的静态数组初始化(MSVC 2019)
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 具有常量引用参数的函数模板专用化
- std::span<const T> 作为函数模板中的参数
- 如何编写一个完美的缩写函数模板?
- 仅在函数模板中为那些定义了函数的类型执行函数
- 如何在C++中伪造虚拟可变参数函数模板?
- 以下代码中的函数模板有什么问题?
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 将显式实例化的函数模板与转换匹配
- 使用定义函数模板别名
- 函数模板返回类型
- C++有什么方法可以在既不调用函数模板也不提供其模板参数的情况下引用函数模板?
- C++ std::functional 中的可变参数函数模板
- 单行函数模板 c++ 的内联性保证
- C++函数模板需要 &for 数组参数
- 概念解析为使用 std::make_signed_t 时意外的函数模板
- 两个函数模板候选项.将一个参数作为引用后,选择不太专业的模板