C++20 概念:int not swappable_with int

Top*_*ort 15 c++ c++-concepts c++20

我正在尝试 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;
}
Run Code Online (Sandbox Code Playgroud)

Dan*_*ica 12

std::swappable_with<T, U>检查是否swap可以using std::swap;使用参数std::declval<T>()和调用(之后)std::declval<U>()。用TUint,两个参数都是右值,这是不能被绑定到std::swap参数,因为这些(非const)左值的引用。


你想知道int不能与 交换int- 是的,你不能写std::swap(1, -1);.

  • 这绝对是疯狂的。这些功能的一般用户应该在这种详细程度和深奥的理论中思考什么?如果你有两个 `int` 对象,它们绝对是可交换的(这是 `std::swap` 的典型例子!),所以 `std::swappable_with&lt;int, int&gt;` 失败是令人难以置信的。谁想出了这些功能‍♂️ (5认同)
  • @AsteroidsWithWings _如果你有两个 int 对象,它们绝对是可交换的。_ — 这不是真的。仅当这两个对象都是左值时,这才成立。如果两者都是右值,或者一个是右值,第二个是左值,则它们不可交换(使用“std::swap”)。 (5认同)
  • @AsteroidsWithWings:“*这些功能的一般用户应该在这种详细程度和深奥的理论中思考?*”当“详细程度和深奥的理论”变得相关时会发生什么?能够区分左值和右值的操作很重要。特别是在这种情况下,如果用户按值而不是按引用获取“T”和“U”,会发生什么情况?该函数可以编译,但不会做任何有用的事情。所以在某种程度上,用户已经必须了解一些“深奥的理论”。 (5认同)
  • @NicolBolas 一种明智的语言应该首先对于常见/明显的情况具有表现力并且易于使用,复杂性是可选的额外内容。C++ 很久以前就忘记了这一点。 (5认同)
  • 公平地说,我要说的是,缓解这种情况的一件事是 `is_swappable&lt;T&gt;` (委托给 `is_swappable_with&lt;T&amp;, T&amp;&gt;`!)似乎为常见/明显的情况提供了“富有表现力且易于使用” “ 角度 (2认同)
  • @DanielLangr 我没有责怪你。这是我们每天都会发表的一次性评论。抱歉冒犯了 (2认同)

Yak*_*ont 9

使用std::swappable_with<T&,U&>- 可交换,关心值类别,通过引用编码,以及类型。

您实际上是在询问是否int可以交换类型的右值。它说“不”;你不能交换到 rvalue ints。

这可能令人困惑,但如果您这样做:

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);
}
Run Code Online (Sandbox Code Playgroud)

它变得更自然一些。在这里,我们使用转发引用,并且参数的 l/rvalue 类别分别T与 和 中的裸类型一起存储U

请注意,如果该类型的对象swappable_with彼此相同,则上述内容可能允许交换右值。