提问者:小点点

使用`std::reference_wrapper<t>`作为始终有效的成员变量而不是指针有什么缺点吗?


我有一个相当常见的问题,我有一个类必须存储一个指向不同类对象的非所有者指针。

我知道:

  • 引用对象的生存期保证比实例的生存期长。
  • 引用的对象传递到构造函数中,除了移动或赋值外,不会更改。
  • 它从不无效。
  • 它用于许多方法。
  • 它可以由许多实例共享。

例如,考虑一个logger类,它不是全局的。

这几点将我引向使用一个保证有效性的引用变量的解决方案:

struct Foo{};

struct Bar{
    Bar(Foo& foo):m_foo(foo){}

Foo& m_foo;
};

最大的缺点是bar不必要地几乎是不可变的--没有分配,没有移动。

我通常做的事情是将foo存储为指针。这解决了大多数问题,只是不再非常清楚指针是否始终有效。此外,它添加了一个新的小的,可以在任何方法中失效,这是不应该发生的。(使其成为常量具有与&)相同的缺点。这使得我在每个方法中添加assert(m_foo),以求安心。

因此,我考虑只存储std::reference_wrapper,它总是有效的,并且保持foo可变。与简单的指针相比有什么缺点吗?我知道任何方法仍然可以将它指向例如局部变量,但是假设这不会发生,因为可能很难获得foo的新的有效实例。至少它比简单的=nullptr;更难

我知道这种方法用于像std::vector这样的容器,所以我认为它是可以的,但是我想知道是否有我应该查找的catch。


共1个答案

匿名用户

因为foo是一个结构,所以每次访问foo的任何成员或字段时都需要调用get()。对于引用或指针,您可以使用“。”或“->”分别用于成员访问。因此reference_wrapper在这方面不是“透明”的。(目前在C++中也没有办法使它“透明”,当然这会很好)。

不会有运行时开销,但代码会因get()调用而拥塞。

如果您不关心这个问题,那么使用reference_wrapper代替指针并没有什么缺点。(实际上reference_wrapper是通过使用指针成员实现的)