[英]Design to avoid binding lvalue reference to temporary for data container and wrapper
I'm struggling with the design of a few (probably two) C++ classes that work together and implement sort of a data container (Vector) and a data wrapper (Integer) that wraps individual vector elements (or better to say the access to it).我正在努力设计几个(可能是两个)C++ 类,它们一起工作并实现某种数据容器(Vector)和一个包装单个矢量元素的数据包装器(Integer)(或者更好地说是对它的访问)。 The Vector simply holds a vector of
int
. Vector 仅包含一个
int
向量。 The Integer/wrapper provides access to an int
(possibly without holding it). Integer/wrapper 提供对
int
的访问(可能不持有它)。
Requirements:要求:
int
(not as a vector of Integer)int
的向量(而不是 Integer 的向量)int
-> Integer possible)int
-> Integer 可能) I fail to design this (see below) without running into the problem where an lvalue reference cannot bind to a temporary.我没有设计这个(见下文)而没有遇到左值引用不能绑定到临时的问题。 I understand that that's not possible and I understand that code is wrong (and why it's wrong).
我知道这是不可能的,并且我理解代码是错误的(以及为什么它是错误的)。 There's no need to explain that lvalue references can't bind to rvalues.
没有必要解释左值引用不能绑定到右值。 I'm struggling to find a solution to above requirements without this problem.
我正在努力寻找没有这个问题的上述要求的解决方案。
How to design this in C++?如何在 C++ 中设计这个? (Can be any modern standard)
(可以是任何现代标准)
#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] );
}
Returning a “temporary” by value doesn't make a copy or even a move (guaranteed as of C++17, though often implemented as a conforming optimization in prior versions).按值返回“临时”不会进行复制甚至移动(从 C++17 开始保证,尽管在以前的版本中经常作为符合优化的方式实现)。 You have to do this, because your
operator[]
needs to form a new wrapper for whatever index.你必须这样做,因为你的
operator[]
需要为任何索引形成一个新的包装器。 (The reinterpret_cast
approach has undefined behavior regardless of other members of Integer
.) Generic code can bind auto&&
to your proxy object because of lifetime extension , and can assign to it, so often need not be aware of the proxy (as is desirable). (无论
Integer
的其他成员如何, reinterpret_cast
方法都具有未定义的行为。)由于生命周期延长,通用代码可以将auto&&
绑定到您的代理 object ,并且可以分配给它,因此通常不需要知道代理(这是可取的)。
Separately, if you want to avoid copying arguments to functions like write_one
that do know about the proxy type, you can accept const Integer&
.另外,如果您想避免将 arguments 复制到像
write_one
这样知道代理类型的函数,您可以接受const Integer&
。 To make that work, make your operator=
const (which sounds weird until you remember that it's not the Integer
that's being modified).为了使它工作,让你的
operator=
const (这听起来很奇怪,直到你记得它不是被修改的Integer
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.