MST

星途 面试题库

面试题:C++ STL 迭代器end边界判断与模板元编程的结合

使用模板元编程和`std::enable_if`,实现一个函数模板,该函数模板接收两个迭代器`it1`和`it2`,只有当这两个迭代器是同一容器类型,且在`it1`到`it2`(不包括`it2`,符合`end()`的边界判断逻辑)范围内的元素满足某个特定条件(例如所有元素都是偶数)时,函数才会被实例化。请写出完整的代码实现,并解释在模板元编程中如何精确处理`end()`迭代器的边界逻辑。
50.0万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
#include <iostream>
#include <vector>
#include <type_traits>
#include <iterator>

// 辅助函数,判断元素是否为偶数
template <typename T>
constexpr bool is_even(T value) {
    return value % 2 == 0;
}

// 主函数模板
template <typename It, typename = std::enable_if_t<
    std::is_same_v<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag> &&
    std::is_same_v<typename std::iterator_traits<It>::value_type, typename std::iterator_traits<std::remove_reference_t<decltype(*std::declval<It>())>>::value_type>
>>
bool check_range(It it1, It it2) {
    for (; it1 != it2; ++it1) {
        if (!is_even(*it1)) {
            return false;
        }
    }
    return true;
}

int main() {
    std::vector<int> vec = {2, 4, 6, 8};
    auto result = check_range(vec.begin(), vec.end());
    std::cout << "Range check result: " << (result? "true" : "false") << std::endl;
    return 0;
}

代码解释

  1. is_even 函数:用于判断一个数是否为偶数。
  2. check_range 函数模板
    • 使用 std::enable_if_t 进行条件约束。
    • 第一个条件 std::is_same_v<typename std::iterator_traits<It>::iterator_category, std::random_access_iterator_tag> 确保传入的迭代器是随机访问迭代器,这样可以方便地进行范围检查。
    • 第二个条件 std::is_same_v<typename std::iterator_traits<It>::value_type, typename std::iterator_traits<std::remove_reference_t<decltype(*std::declval<It>())>>::value_type> 确保两个迭代器指向的元素类型相同。
    • 函数体遍历 it1it2 的范围,检查每个元素是否为偶数。
  3. main 函数:创建一个 std::vector<int> 并调用 check_range 函数,输出结果。

处理 end() 迭代器的边界逻辑

在模板元编程中,end() 迭代器的边界逻辑主要依赖于迭代器自身的特性和标准库的约定。通过 std::iterator_traits 获取迭代器的类型信息,如 iterator_category 来确保迭代器支持相应的操作(如随机访问)。在函数体中,使用 it1 != it2 作为循环条件,这是标准库中 end() 迭代器的边界判断逻辑,即 end() 迭代器指向容器最后一个元素的下一个位置,循环在 it1 到达 it2 时停止,不包括 it2 指向的位置。