我正在尝试C ++ 20的概念,并且std::swappable_with
未定义(Visual Studio,使用/std:c++latest
)或它的约束与下面的MCVE不匹配(g ++ 10,使用-std=c++2a
)-即int
不能与int
(!)交换。有什么解决办法?如果int
无法与int
交换,我认为没有任何作用。
#include <concepts>
template <typename T, typename U>
requires std::swappable_with<T,U>
void mySwap(T& t, U& u)
{
T temp = t; t = u; u = temp;
}
int main()
{
int x, y;
mySwap(x, y);
return 0;
}
答案 0 :(得分:12)
std::swappable_with<T, U>
检查是否可以使用参数swap
和using std::swap;
调用std::declval<T>()
(在std::declval<U>()
之后)。在T
和U
为int
的情况下,两个参数均为 rvalues ,它们不能绑定到std::swap
参数,因为它们是(非const )左值引用。
您想知道int
不能与int
交换吗-是的,您不能写std::swap(1, -1);
。
答案 1 :(得分:9)
使用std::swappable_with<T&,U&>
-可以交换,关心值类别,按引用编码和类型。
您实际上是在询问是否可以交换类型int
的右值。它说“不”;您不能交换为右值int
。
这可能会令人困惑,但是如果您这样做:
template <class T, class U>
requires std::swappable_with<T,U>
void mySwap(T&& t, U&& u) {
auto temp = std::forward<T>(t);
t = std::forward<U>(u);
u = std::move(temp);
}
它变得更加自然。在这里,我们使用转发引用,并且参数的l / rvalue类别分别与裸类型一起存储在T
和U
中。
请注意,如果该类型的对象彼此为swappable_with
,则上述内容可能允许交换右值。