我正在尝试再次做一些奇怪的事情。
好的,这是一般的想法。我想要一个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();
当然,我可能也想要一个owningstack
or 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
,以节省将几乎相同的类重写四次?stack
vector
也许我可以引入一个中间类,某种包装器?那么owned<list<T>>
可以继承list<refwrapper<T>>
还是什么?我知道 boost 有一个reference_wrapper
,但我不确定它是否适合这种情况。