首页 > 解决方案 > 避免将左值引用绑定到临时数据容器和包装器的设计

问题描述

我正在努力设计几个(可能是两个)C++ 类,它们一起工作并实现某种数据容器(Vector)和一个包装单个矢量元素的数据包装器(Integer)(或者更好地说是对它的访问) )。Vector 仅包含 的向量int。Integer/wrapper 提供对 an 的访问int(可能不持有它)。

要求:

  1. Wrapper/Integer 必须作为左值可用
  2. 数据容器应将数据保存为一个向量int(而不是整数向量)
  3. 包装器还包含一些其他数据成员(不能重新解释强制int转换 -> 可能的整数)

我没有设计这个(见下文)而没有遇到左值引用不能绑定到临时的问题。我知道这是不可能的,并且我理解代码是错误的(以及为什么它是错误的)。没有必要解释左值引用不能绑定到右值。我正在努力寻找没有这个问题的上述要求的解决方案。

如何在 C++ 中设计这个?(可以是任何现代标准)

#include<vector>
        
class Integer
{
  int& ref_t;
  bool other_data_member;

public:
  Integer(int& rhs): ref_t(rhs) {}

  Integer& operator=( int i )
  {
    ref_t = i;
    return *this;
  }
};



class Vector
{
  std::vector<int> data;

public:
  Vector(): data(10) {}
  
  Integer& operator[](int i)
  {
    return Integer( data[i] ); // caution: this doesn't work
  }
};



void write_one( Integer& i )
{
  i = 1;
}


int main()
{
  Vector v;
  write_one( v[5] );
}

标签: c++

解决方案


按值返回“临时”不会进行复制甚至移动(从 C++17 开始保证,尽管在以前的版本中通常作为符合优化的方式实现)。你必须这样做,因为你operator[]需要为任何索引形成一个的包装器。(该方法具有未定义的reinterpret_cast行为,无论.Integerauto&&

另外,如果您想避免将参数复制到write_one知道代理类型的函数中,您可以接受const Integer&. 为了使它起作用,请制作你的operator= const(这听起来很奇怪,直到你记得它不是Integer被修改的那个)。


推荐阅读