【发布时间】:2020-01-19 21:41:11
【问题描述】:
我试图在以下情况下初始化右值引用成员:struct A 是一个聚合,class B 有一个用户定义的构造函数,因此它不是聚合。根据cppreference这里,
struct A {
int&& r;
};
A a1{7}; // OK, lifetime is extended
A a2(7); // well-formed, but dangling reference
我的struct A 中的引用应该被正确初始化并且临时字符串应该被扩展,但事实并非如此。
对于我的class B,在同一个 cppreference 页面中:
绑定到构造函数初始化列表中的引用成员的临时绑定仅持续到构造函数退出,而不是只要对象存在。 (注意:从 DR 1696 开始,此类初始化格式不正确)。 (直到 C++14)
但我仍然遇到/std:c++latest 的 MSVC 问题。我错过了什么吗?
struct A
{
std::string&& ref;
};
class B
{
std::string&& ref;
public:
B(std::string&& rref):ref(std::move(rref)){}
void print() {std::cout<<ref<<'\n';}
};
int main()
{
A a{ std::string{"hello world"} };
std::cout<<a.ref<<'\n'; //garbage in MSVC with c++latest, correct in GCC9.2
B b{ std::string{"hello world"} };
b.print(); //same
}
编辑:请告诉我,如果我首先在这两种情况下得到悬空参考。而对于 MSVC,版本是最新更新,v19.24.28315
EDIT2:好的,我实际上对 cppreference 的解释感到困惑。我并不是专门要求 C++20。请告诉我在哪个 C++ 版本下,代码格式是否正确。
EDIT3:是否有适当的方法来初始化非聚合类的右值引用成员?由于将其绑定到成员初始化器列表中的临时值是错误的(直到 C++14,这是否意味着它自 C++14 以来就很好?)并且将临时值传递给期望右值的构造函数不能将其生命周期延长两次.
【问题讨论】:
-
引用不支持你的论点,即
A a1{7};延长了临时的寿命。 -
/std:c++latest没有指定 C++ 标准 (这在这个问题中可能非常相关)。 最新 c++ 版本取决于 MSVC 版本。如果能指定C++版本可能会更好 -
Fwiw,应该避免引用成员。这对于右值引用更是如此,因为当它们是类成员时,它们不会延长临时对象的生命周期
-
@HolyBlackCat 这是新的 C++20 括号聚合初始化语法。 GCC 中继已经支持它:godbolt.org/z/K-4CXL
-
@NathanOliver 您能否为右值引用提供参考,当它们是类成员时,它们不会延长临时对象的生命周期?
标签: c++