我想交换两个固定大小的整数数组。
与直觉相反,以下内容无法编译,因为没有swap找到匹配的实例。
#include <array>
#include <utility>
int main()
{
std::array<int,3> a, b;
std::swap< std::array<int,3> >( a, b );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我觉得这很令人惊讶。但是,用编译替换交换std::swap(a,b)并且(根据 VSCode)具有签名
inline void std::swap<int, 3UL>(std::array<int, 3UL> &__one, std::array<int, 3UL> &__two)
Run Code Online (Sandbox Code Playgroud)
我也无法理解。
问:这是怎么回事?
for*_*818 17
您正在寻找的重载是(来自cppreference):
Run Code Online (Sandbox Code Playgroud)template< class T, std::size_t N > constexpr void swap( std::array<T, N>& lhs, std::array<T, N>& rhs ) noexcept(/* see below */);
正如错误报告所示,编译器无法找到std::swap()匹配的可行重载std::swap<std::array<int,3>>。
这将是显式提供模板参数的“正确”方法:
#include <array>
#include <utility>
int main()
{
std::array<int,3> a, b;
std::swap<int,3>( a, b );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我怀疑在某种情况下你真的想这样做。
PS:您还可以在从 VSCOde 获得的签名中看到:std::swap<int, 3UL>不是std::swap<std::array<int,3UL>>。然而,查看实现有时可能会产生误导,我建议首先查阅文档。
use*_*670 10
该问题似乎是由 libstdc++ 实现引起的。它强制要求
(源tuple-like)的适当“基本”变体中使用的类型:std::swap
template<typename _Tp>
_GLIBCXX20_CONSTEXPR
inline
#if __cplusplus >= 201103L
typename enable_if<__and_<__not_<__is_tuple_like<_Tp>>,
is_move_constructible<_Tp>,
is_move_assignable<_Tp>>::value>::type
#else
void
#endif
swap(_Tp& __a, _Tp& __b)
Run Code Online (Sandbox Code Playgroud)
即使标准没有提到这样的限制:
20.2.2
swap [utility.swap]
template<class T>
constexpr void swap(T& a, T& b) noexcept(see below );
1 备注:该函数是指定的定制点(16.5.4.2.1),并且不应参与重载决策,除非is_move_constructible_v<T>istrue和is_move_assignable_v<T>istrue。里面的表达式noexcept相当于:is_nothrow_move_constructible_v<T> && is_nothrow_move_assignable_v<T>
2 要求:类型T应为Cpp17MoveConstructible(表 26)和Cpp17MoveAssignable(表 28)。
代码适用于 vc++ ,其中库仅根据标准要求检查is_move_constructible和。is_move_assignable