正在研究 c++标准库的代码, 我用的是 VS2019 ,在~VS 2019\Microsoft Visual Studio\VC\Tools\MSVC\14.22.27905\include\utility 文件内,有关 swap 的函数,其中一个重载如下
// FUNCTION TEMPLATE swap
template <class _Ty, size_t _Size, class> //这个 class
inline void swap(_Ty (&_Left)[_Size], _Ty (&_Right)[_Size])
_NOEXCEPT_COND(_Is_nothrow_swappable<_Ty>::value) { // exchange arrays stored at _Left and _Right
if (&_Left != &_Right) { // worth swapping, swap ranges
_Ty* _First1 = _Left;
_Ty* _Last1 = _First1 + _Size;
_Ty* _First2 = _Right;
for (; _First1 != _Last1; ++_First1, ++_First2) {
_STD iter_swap(_First1, _First2);
}
}
}
这个 swap 函数还有个重载版本,也有这个情况
template <class _Ty, class> //这里也是同样
inline void swap(_Ty& _Left, _Ty& _Right) _NOEXCEPT_COND(is_nothrow_move_constructible_v<_Ty>&&
is_nothrow_move_assignable_v<_Ty>) { // exchange values stored at _Left and _Right
_Ty _Tmp = _STD move(_Left);
_Left = _STD move(_Right);
_Right = _STD move(_Tmp);
}
我像问下这个 class 是什么意思
1
geelaw 2022-12-28 22:40:44 +08:00 1
声明一个匿名模板参数而已,等同于
int foo(int bar, int) { } 里面的第二个 int ,或者更常见的情况是 struct A { A operator++(int) { return A{}; } }; 里面的 int 。 在 Visual C++ 提供的头文件 type_traits 里面有 std::swap 的声明,那里定义了第二个类型参数的默认值,主要是用来做 SFINAE 的,因为从 C++17 开始 std::swap 只有在类型是可移动构造且可移动赋值时才存在。 #if _HAS_CXX17 template<class _Ty, class = enable_if_t<is_move_constructible_v<_Ty> && is_move_assignable_v<_Ty>>> inline #else template<class _Ty, class = void> inline #endif void swap(_Ty&, _Ty&) _NOEXCEPT_COND(is_nothrow_move_constructible_v<_Ty> && is_nothrow_move_assignable_v<_Ty>); 假设在 C++17 模式下编译且 B 是不可移动构造的类型,则 B b; std::swap(b, b); 会失败,因为此时 enable_if_t 会失败,从而让第二个 class 参数没有默认值,此时第二个参数无法推断,因此编译失败。 |