
正在研究 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 声明一个匿名模板参数而已,等同于 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 参数没有默认值,此时第二个参数无法推断,因此编译失败。 |