我正在尝试再次做一些奇怪的事情。
好的,这是一般的想法。我想要一个std::list(vector等等)实际上拥有它们包含的对象。我想将值移入其中,并通过引用访问它们。
使用 unique_ptr 列表的示例:
using namespace std;
list<unique_ptr<T>> items; // T is whatever type
items.push_back(make_unique(...));
items.push_back(make_unique(...));
for ( unique_ptr<T> item : items )
item.dosomething();
跟我到现在?好的。现在,让我们用堆栈语义和右值引用来做这件事。由于显而易见的原因,我们不能只使用 a list<T&&>,所以我们必须创建一个新类:
using namespace std;
owninglist<T> items;
items.push_back(T());
items.push_back(T());
for ( T& item : items )
item.dosomething();
当然,我可能也想要一个owningstackor owningvector,所以理想情况下我们希望它被模板化:
owning<std::list<T>> items;
该类owning<U<T>>应该继承基础集合具有的任何push_back()等pop_front()功能。大概要实现这一点,我需要编写一个通用基类,并为具有不寻常功能的集合派生明确的特化:
template<typename T> owning<std::queue<T>> : owningbase<T> {
void push_front() { ... }
}
我被困在迭代器上。begin()and函数应该返回一个迭代器,其end()工作方式与基础集合的迭代器相同,除了通过左值引用而不是按值operator*()返回项目。
我们需要某种方法将项目的所有权再次从列表中转移出去。也许迭代器可以有一个operator~将项目作为右值返回,从列表中删除项目并使迭代器无效?
当然,所有这一切都是假设std::list可以说服底层(或其他任何东西)采用右值。如果push_back()将值复制为左值,那么这一切都不起作用。从头开始编写容器会更好吗?list如果我这样做了,是否有某种方法可以将、和的大部分代码放入单个基类中queue,以节省将几乎相同的类重写四次?stackvector
也许我可以引入一个中间类,某种包装器?那么owned<list<T>>可以继承list<refwrapper<T>>还是什么?我知道 boost 有一个reference_wrapper,但我不确定它是否适合这种情况。