看代码说话
template <typename Iterator>
auto distance(Iterator begin, Iterator end) {
using Traits = std::iterator_traits<Iterator>;
if constexpr (std::is_base_of_v<std::random_access_iterator_tag, typename Traits::iterator_category>) {
return end - begin;
} else {
auto result = typename Traits::difference_type();
for (auto it = begin; it != end; ++it) {
++result;
}
return result;
}
}
上面的代码用来判断两个iterator之间的距离。主要逻辑是判断iterator是否是可随机访问的iterator然后作分支处理,可以随机访问的迭代器直接把iterator相减。
在constexpr if
语句中,条件的值必须是可按语境转换到 bool 类型的经转换常量表达式。若其值为 true,则舍弃 false分支语句(若存在),否则舍弃 true分支语句。有意思的一点是,被舍弃语句中的 return 语句不参与函数返回类型推导,也就是说两个分支语句中的return推倒出来的类型允许不一样。
如果没有C++17这种怎么写呢?就是比较麻烦。
一可以加一个参数,但是每个tag写一个
template <typename Iterator>
auto distance(Iterator begin, Iterator end, std::bidirectional_iterator_tag); // one for each tag type
或者用SFINAE写两个
template <typename Iterator>
auto distance(Iterator begin, Iterator end,
typename std::enable_if_t<std::is_base_of_v<一大坨>>* = nullptr);
发表回复