我正在编写一些基于容器或可迭代的算法。for( : )
基本上,我对支持样式迭代的对象进行操作(我很少for( : )
直接使用,但遵循它如何查找begin
和end
迭代器)。
在std
库中,大多数可迭代对象都是容器。他们都拥有自己的数据,并让您查看。
当算法通过右值引用获取容器时,这意味着容器的内容也可以自由获取。例如,如果我写concatinate
了两个vector
s 并返回第三个,如果两个vector
s 都是move
d,我们将希望重用第一个,vector
然后使用move_iterator
s 从第二个中取出数据vector
以提高效率。
但是,对于概念上相似的 C++1ystring_view
和类型,我们拥有不是容器的可迭代对象,而是容器中的视图。从语义上讲,我相信视图的行为类似于指针,因此它们的“按值”复制是将视图复制到容器中,而不是它们引用的数据。如果我string_view
通过右值引用来获取样式视图,这并不意味着它拥有内容:从内容移动是不合理的,只是因为指针本身是右值而移动指针的内容。
同时,容器遵循值语义,并且因为它们是右值而移动它们的内容是有效的。
因为string_view
这不是问题,但我编写了更通用的view
类,例如contiguous_range_view
,它可以让您对 avector
或array
or的子集进行操作,arr[]
就好像它是一个大小不可变的缓冲区一样。
这些视图并不总是将其内容视为const
,但它们并不拥有其内容。所以视图是右值并不意味着它们的内容是右值!
我的算法喜欢concatinate
在这里遇到问题。视图与容器几乎没有区别,右值容器可以有效地被移出,而右值视图则不是。按值返回视图的函数是一种很好的模式,因为视图在语义上是指针类型。
我正在寻找一种很好、干净的方式来区分容器和视图。是否有计划string_view
通过我现在可以模拟或挂钩的某些属性或标签在 C++1y 中进行区分?如果没有,有没有好的模式?
如果我设法阻止视图被意外移动,有时我仍然需要能够从它们移动,所以我需要一种方法来将视图标记为移动候选而不是右值引用. 我怀疑一个make_move_range
函数可能会解决这个问题(它需要一个可迭代的范围,并适用std::make_move_iterator
于begin
and end
)。