gpt4 book ai didi

c++ - 为什么在 C++20 中需要 std::forward 来检查一个类型是否可以转换为另一个类型而不缩小

转载 作者:行者123 更新时间:2023-12-05 05:31:00 24 4
gpt4 key购买 nike

为了检查一个类型是否可以在不缩小到另一个类型的情况下进行转换,建议 here像这样使用 std::forward 和 std::type_identity_t 来实现它:

template<class T, class U>
concept __construct_without_narrowing = requires (U&& x) {
{ std::type_identity_t<T[]>{std::forward<U>(x)} } -> T[1];
};

我从中明白为什么会这样:

To{std::declval<From>()}

给出了不正确的结果,但是当我尝试使用论文中的另一个想法来简化它时,只写

template <typename From, typename To>
concept WithoutNarrowing =
requires (From x) {
{(To[1]){x}}
->std::same_as<To[1]>;
};

似乎给出了相同的结果。必须发生什么情况才能给出不同的结果?还是等价的?为什么这里使用 std::forward?

最佳答案

这是涉及某种函数/构造函数参数的类型特征的常用方法。

UT 的类型应该构造,但如果我们要讨论构造,我们还需要考虑参数的值类别。它可能是左值或右值,这可能会影响例如哪个构造函数可用。

我们的想法是将右值参数大小写映射到非引用 U或右值引用 U左值参数大小写为左值引用 U , 匹配 decltype 中表达式的映射以及函数调用表达式中具有值类别的返回类型。

然后,通过引用折叠规则,U&&如果构造函数参数是左值,则将是左值引用,否则将是右值引用。然后使用 std::forward意味着当 U 时,我们给构造的实际参数确实是一个左值参数。本来是为了表示一个和一个右值参数。

您的方法使用 {(To[1]){x}}不使用转发,所以总是只测试是否可以在不缩小的情况下从左值进行构造,这不是预期的,例如U是非引用。


您的方法更加不正确,因为 (To[1]){x}在标准 C++ 中不是有效语法。如果X是你可以拥有的类型 X{x}(X)x , 但不是 (X){x} .然而,最后一种语法是 C 的一部分,并在那里称为复合文字。因此,C++ 编译器可能会支持它作为 C++ 的扩展。这就是为什么最初的实现使用 std::type_identity_t 的迂回方式的原因。 .


该实现似乎也是为 C++20 概念的早期草案编写的。现在无法使用 -> 右侧的类型直接针对需求。取而代之的是一个概念,即 -> std::same_as<T[1]> , 必须按照您建议的实现方式使用。

关于c++ - 为什么在 C++20 中需要 std::forward 来检查一个类型是否可以转换为另一个类型而不缩小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74473008/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com