理解c++ move_constructible概念实现

bt1cpqcv  于 2023-08-09  发布在  其他
关注(0)|答案(1)|浏览(110)

我从cppreference得到了c++概念move_constructible的以下实现

template<typename _Tp>
concept move_constructible =
    constructible_from<_Tp, _Tp> &&
    convertible_to<_Tp, _Tp>;

字符串
我不明白这为什么有用。我假设任何类型都可以转换为自身,所以第二个要求是毫无意义的(上帝,我一定是在某些方面错得很离谱)。另外,对于第一个要求,我希望像constructible_from<_Tp, _Tp&&>这样的东西来检查类型是否可以从rvalue-ref构造(因此,移动)。
请解释一下这个实现是如何工作的。

4si2a6ki

4si2a6ki1#

大多数traits/concept会自动将&&添加到“源”参数的类型中(传递给函数的东西,如std::is_invocable,或从函数构造的东西,如std::is_constructible)。
constructible_from<A, B>等价于constructible_from<A, B &&>&&会自动添加到第二个参数中,但不会添加到第一个参数中),convertible_to<A, B>等价于convertible_to<A &&, B>
请注意,如果一个类型已经包含&,则向其添加&&没有任何效果。因此,虽然TT &&在这里是等价的,但T &不是。
这可以从那些以std::declval<T>()定义的trait/概念中推断出来,它返回T &&
关于std::declval<T &>()返回T &的原因,请参阅reference collapsing

**注:**有一个例外:将一个不完整的类型(例如一个声明但未定义的类)作为非第一个参数传递给is_constructible(和constructible_from)是UB,一些编译器会拒绝它。手动追加&&可以绕过这条规则,因此在泛型代码中,您应该始终首选将T &&传递给这些traits。

但是对于move_constructible来说没有区别,因为它首先对不完整类型没有意义。

相关问题