is_constructible_v<std::string&&, std::string&&>是什么意思?

What does is_constructible_v<std::string&&, std::string&&> mean by?

提问人:myoldgrandpa 提问时间:8/28/2023 最后编辑:myoldgrandpa 更新时间:8/29/2023 访问量:142

问:

我能理解什么是. 但是什么意思?is_constructible_v<std::string, std::string&&>is_constructible_v<std::string&&, std::string&&>

和 和有什么不一样?is_constructible_v<std::string, std::string&&>is_constructible_v<std::string&&, std::string&&>

我认为这意味着从右值构造 rvalue。但我不清楚这意味着什么。如果 T 只是可构造的,它的构造函数总是可以用作右值。这就是构造右值的意义吗?is_constructible_v<std::string&&, std::string&&>constructing rvalue

C++ 构造函数 C++17 类型特征 rvalue

评论

0赞 user3840170 8/28/2023
is_constructible_v<std::string&&, std::string&&>是什么意思?

答:

5赞 Ted Lyngmo 8/28/2023 #1

std::is_constructible_v<std::string&&, std::string&&>测试是否

std::string&& obj(std::declval<std::string&&>());

格式良好(参见 [meta.unary.prop] p9),确实如此。您可以创建右值引用,如下所示:

std::string&& obj(std::string{}); // string&& from string&&

评论

0赞 Jan Schultke 8/28/2023
值得注意的是,这两个语句的作用不同;第一个是绑定对 xvalue 的引用,第二个是执行临时具体化。目前,我认为唯一的区别是一个使用私有析构函数/构造函数,而另一个则不使用。
0赞 Ted Lyngmo 8/29/2023
@JanSchultke 我不是100%确定你的意思。我只是试图回答它的作用(并希望它值得一些东西)。测试当然可以返回,但至少在 C++14 中意味着什么:-)......感谢您的编辑!干杯!false<foo, foo&&>true<foo&&, foo&&>
1赞 Ted Lyngmo 8/29/2023
@myoldgrandpa 使用可能受到限制,但它旨在显示类型特征测试的内容。“it can't be refer after that line” - 是的,是右值引用。“如果 std::string obj(std::string{}) 格式正确,我认为 std::string&& obj(std::string{}) 格式也很好” - 是的,但反之可能并非如此。但是,如果可以将右值引用绑定到任何值引用,则测试的有用性值得怀疑,因为您始终可以这样做。objT
1赞 Ted Lyngmo 8/29/2023
...如果测试不是,那就不同了,但是is_constructible_v<T&&, T>is_constructible_v<T&&, U>
1赞 Ted Lyngmo 8/30/2023
“不过,测试是否可以将右值引用绑定到任何 T 的有用性是值得怀疑的,因为你总是可以这样做。”...根据。不过,这在现实中可能并不成立。is_constructible
1赞 HolyBlackCat 8/28/2023 #2

&/&&在第一个参数和其余参数中具有不同的含义。is_constructible

在第二个(以及以下任何)参数中,它们指定值类别:for lvalue 和 / for rvalue。& &&

在第一个参数中,/ 是我们正在构造的变量类型的一部分,而不是值类别。&&&

因此,我们正在构造一个 from a rvalue type .is_constructible_v<std::string, std::string&&>std::stringstd::string

在 中,我们从 类型的右值构造一个(引用,而不是字符串)。is_constructible_v<std::string&&, std::string&&>std::string&&std::string


下面是一个如何发生的例子:

std::string a;
std::string &&b = std::move(a); // `move` here returns an rvalue of type `std::string &&`

令人困惑的是,接近和返回类型也意味着微妙不同的东西。前者是参考。而后者使返回 xvalue,而不是 prvalue(按值返回时)或左值(返回引用时)。严格来说,后者不会产生任何参考。&&b&&movebmove&

评论

0赞 myoldgrandpa 8/30/2023
但是在您的示例中,不会发生右值的构造,因为 std::move 只是将“a”转换为右值的类型。你的例子如何解释我的问题?
0赞 HolyBlackCat 8/30/2023
@myoldgrandpa 正在构造引用。(或者更确切地说是“创建”,因为只能“构造”类实例。是的,不会创建新的,但会创建一个新的引用。bstd::string
1赞 HolyBlackCat 8/30/2023
说句迂腐的话,说“重值的构造”没有多大意义。相反,它是“构造(或创建)右值引用”。尽管名称不同,但右值引用和右值是不同的东西,这就是我在这里试图表达的观点。
0赞 myoldgrandpa 8/30/2023
那么,在用你的示例构造右值引用时,是否调用了构造函数?根据我的理解,是为了检查是否可以毫无问题地调用相应的构造函数。但在您的示例中,可能不调用构造函数。我说得对吗?is_constructible
1赞 HolyBlackCat 8/30/2023
@myoldgrandpa“用于检查是否可以调用相应的构造函数” 只有当第一个参数是类类型时才成立,其他类型(例如引用)没有构造函数。通常,它检查指定类型的变量是否可以使用指定的参数进行初始化。“使用示例构造右值引用时,是否调用了构造函数”不,但这不是我们要检查的。我们正在检查是否可以使用 类型的右值初始化引用。std::string&&std::string