编译器: MSVC v142
所属文件: xutility
位置(行): 485
函数名称:_Idl_distance
函数描述:
计算两个Iterator
指针的距离, 白话一点就是,获取Iterator
的length
, 类似python
里面获取一个列表长度的内置方法l.len()
.
源码:
template <class _Checked, class _Iter>
inline auto _Idl_distance(const _Iter& _First, const _Iter& _Last) {
// tries to get the distance between _First and _Last if they are random-access iterators
if constexpr (_Is_random_iter_v<_Iter>) {
return static_cast<_Iter_diff_t<_Checked>>(_Last - _First);
} else {
(void) _First; // TRANSITION, VSO#486357
(void) _Last; // TRANSITION, VSO#486357
return _Distance_unknown{};
}
}
获取Iterator
的length
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::copy;
using std::vector;
int main(void) {
vector<int> a {1,2,3,4,5,6,7,8,9};
auto start = a.begin();
auto stop = a.end();
auto start_ptr = start._Unwrapped();
auto stop_ptr = stop._Unwrapped();
cout << stop - start << endl; // output: 9
return 0;
}
关键语句解读
if constexpr (expression) {}
编译期选择分支代码进行编译, 也就是中命中了第一个条件, 就仅生成和编译第一个条件中的代码, 其他代码不生成, 也不编译.
_Is_random_iter_v<_Iter>
是根据Iterator
的tag
类型,尝试转换, 看看是否能够转换成random_access_iterator_tag
, 如果能转换成功, 那么就返回true
, 转换失败则返回false.
_Iter_diff_t<_Checked>
其中_Checked
是一个模板参数(Iterator
类型), _Iter_diff_t
负责提取_Checked
的difference_tye
属性, 这个属性是一个long long
, 因此简化来看就是: _Iter_diff_t<_Checked>
== long long
.
组合起来看, 就是:static_cast<_Iter_diff_t<_Checked>>(_Last - _First);
== static_cast<long long>(_Last - _First);
,整个语句肯定是先计算_Last - _First
得出一个int数值, 然后再使用static_cast<long long>(9)
转换成一个 long long
类型的值.
参考
Compiler Support for Type Traits (C++/CLI and C++/CX)
_Is_random_iter_v
里面引用了一个 __is_convertible_to
是 msvc
为 type_trait
拓展的一个函数功能, 无法查看到源码, 所以智能看这个链接的解释和样例去理解它的意思..