c++ - 如何编写一个以比较运算符为参数的函数模板?
问题描述
我的任务是编写一个函数模板,该模板将一个区间作为前 2 个参数,将一个比较运算符作为第三个参数,并使用此比较运算符决定它是否是单调的。
用法示例:
1.
int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
monotonic(a, a+10, std::greater<int>())
const char *a[] = { "apple", "cherry", "plum", "pickle" };
std::vector<std::string> s(a, a+4);
std::ostream_iterator<std::string> os(cout, ", ");
std::copy(s.begin(), s.end(), os);
monotonic(s.begin(), s.end(), std::greater<std::string>())
我一直在谷歌搜索,发现模板应该看起来像这样:
template<class Iter, typename Comparator>
bool monotonic(Iter first, Iter last, Comparator comp){
}
但是,我无法弄清楚我应该如何使用它comp
来实际比较数字、字符等。
解决方案
设计 API 和编写代码的最佳方式是使用测试。
template<typename T, typename F = std::less<typename std::iterator_traits<T>::value_type>>
bool isMonotonic(T b, T e, F cmp = {})
{
if (b == e) return true;
auto last = b++;
while (b != e) {
if (!cmp(*last, *b)) return false;
last = b++;
}
return true;
}
TEST_CASE("isMonotonic") {
constexpr int growingTale[] = { 1, 2, 7, 10, 22};
constexpr int notDecrasingTale[] = { 2, 2, 2, 10, 22};
SECTION("Empty range is alawyas monotonic") {
auto sameBeginEnd = std::begin(growingTale);
CHECK(isMonotonic(sameBeginEnd, sameBeginEnd));
CHECK(isMonotonic(sameBeginEnd, sameBeginEnd, std::greater{}));
}
SECTION("One element range is always monotonic") {
auto b = std::begin(growingTale);
CHECK(isMonotonic(b, b + 1));
CHECK(isMonotonic(b, b + 1, std::greater{}));
}
SECTION("growing table is monotonic for less operator, but is not for greater operator") {
auto b = std::begin(growingTale);
auto e = std::end(growingTale);
CHECK(isMonotonic(b, e));
CHECK(!isMonotonic(b, e, std::greater{}));
}
SECTION("Not decrasing range is not monotonic, unless <= operator is used") {
auto b = std::begin(notDecrasingTale);
auto e = std::end(notDecrasingTale);
CHECK(!isMonotonic(b, e));
CHECK(!isMonotonic(b, e, std::greater{}));
CHECK(isMonotonic(b, e, std::less_equal{}));
}
}
推荐阅读
- android - Firebase Firestore 生成两个 ID 代替一个
- snowflake-cloud-data-platform - 将数据从 Snowflake 引入 Azure 数据目录
- java - 在两个单独的项目之间创建文件的问题
- google-app-engine - 我无法将调度配置文件部署到 App Engine
- sql - 将 MS Access IIF 转换为 SQL Server CASE 语句
- python - 如何使用循环生成多个按钮?
- javascript - Javascript & Html - 当前月份列表不显示当前并且还显示错误的 UTC 日期
- docker - nginx 重定向到多 docker 容器
- javascript - JavaScript:是否可以仅在移动设备上禁用点击事件?
- javascript - 如何在 md-table 中使用带有 ng-repeat 的 md-radio-group?