作为对象字段的右值引用
rvalue reference as an object field
#include <iostream>
struct Bar
{
int nb_;
Bar(int nb) :nb_(nb){}
~Bar()
{
std::cout << "~Bar" << "n";
}
};
struct Foo
{
template<class T>
Foo(T&& param) :bar_(std::move(param))
{
std::cout << "Foo" << "n";
}
~Foo()
{
std::cout << "~Foo" << "n";
}
Bar&& bar_;
};
int main()
{
{
Foo foo(Bar(1));
}
std::cin.ignore();
}
//Output:
Foo
~Bar
~Foo
这个程序是否合法C++?一旦 Foo 构造函数完成,bar_ 是否会成为一个悬而未决的引用?
如果这在C++标准方面是不合法的,那么什么时候将右值引用作为字段有用?
一旦Foo构造函数完成,
bar_
会成为一个悬而未决的引用吗?
差一点。它在Bar(1)
创建的临时被破坏时成为悬空引用:在全表达式Foo foo(Bar(1))
的末尾。
这也显示了右值引用成员的使用示例,例如forward_as_tuple
:
struct woof
{
using my_tuple = std::tuple<std::vector<int>, std::string>;
my_tuple m;
woof(my_tuple x) : m(std::move(x)) {}
};
std::vector<int> v{1,2,3,4,5};
woof w( forward_as_tuple(std::move(v), std::string{"hello world"}) );
forward_as_tuple
可以存储右值引用(这里:在tuple<vector<int>&&, string&&>
中),woof
的 ctor 仍然可以使用它来移动v
和 std::string{"hello world"}
创建的临时引用。
是的,bar_
将在构造函数完成后成为悬而未决的引用。
存储引用很少有意义,但存在一些情况。我认为不同类型的引用之间没有任何区别。存储的引用引用另一个对象,您需要确保该对象在使用引用时仍然有效。
请注意,如果您编写
Bar b( 1 );
Foo foo(std::move(b));
foo
不会移动b
,它只是存储对它的引用。 b
仍然有效,可以使用。仅当您有一个实际从存储引用中移动的 Foo
成员时,才会移动b
。
相关文章:
- 在 C++20 之前,在带有常量或引用字段的"A"上调用 'std::vector<A>
- 对象引用中的字段以不同的方法返回不同的值
- 将字段(在类中)定义为引用的缺点是什么?
- 为什么在具有引用字段的类中隐式删除复制运算符
- 通用引用和压缩字段
- C++ Arduino:向下转换后,子字段不引用原始地址
- 如何匹配通过引用传递给模拟函数的结构字段
- Const 引用字段作为类中的只读属性C++
- 正在取消引用自定义结构字段的迭代器
- 作为对象字段的右值引用
- C++:为智能指针的字段隐式保留右值引用
- 来自 gcc 原子标头的对我的类静态字段错误的未定义引用
- 为什么我无法返回对打包字段的引用?
- 如何使用 GNU C++引用继承类的字段
- 使用 std::vector、boost::variant 和带有引用字段的类型
- 引用其他对象作为引用类字段
- 是否声明抽象类型的字段?首选指针或引用
- "Undefined reference"尝试引用静态字段
- 无法引用非静态字段"x"
- 我无法通过类 Artist 的公共方法修改任何私有字段。我尝试在函数名称之前添加引用(&),但崩溃了