STL-Like范围,如果我这样做会出现什么问题?

时间:2010-01-31 00:19:02

标签: c++ stl standards

我正在编写(作为自学练习)一个简单的STL-Like范围。它是一个不可变随机访问“容器”。我的范围只保留其起始元素,元素数量和步长(两个连续元素之间的差异):

struct range
{
...
private:
  value_type m_first_element, m_element_count, m_step;
};

因为我的范围不包含元素,所以它使用以下方法计算所需的元素:

// In the standards, the operator[]
// should return a const reference.
// Because Range doesn't store its elements
// internally, we return a copy of the value.
value_type operator[](size_type index)
{
    return m_first_element + m_step*index;
}

正如您所看到的,我没有像标准所说的那样返回const reference。现在,我可以假设const reference和元素的副本在使用标准库中的非变异算法方面是相同的吗?

非常感谢有关该主题的任何建议。


@Steve Jessop:很好,你提到了迭代器。

实际上,我使用了sgi as my reference。在该页面的末尾,它说:

假设x和y是来自相同范围的迭代器:

  

不变量身份
  x == y if and only if &*x == &*y

所以,它归结为我实际问过的同一个原始问题:)

4 个答案:

答案 0 :(得分:1)

STL容器中的项目预计会一直被复制;例如,考虑何时必须重新分配向量。所以,你的例子很好,除了它只适用于随机迭代器。但我怀疑后者可能是设计上的。 :-P

答案 1 :(得分:1)

您希望您的范围可用于STL算法吗?使用第一个和最后一个元素会不会更好? (考虑到end()是必需/使用的事实,你必须预先计算它的性能。)或者,你指望连续的元素(这是我的第二点)?

答案 2 :(得分:1)

标准算法并没有真正使用operator[],它们都是根据迭代器定义的,除非我忘记了重要的事情。是否计划在operator[]之上为“范围”重新实现标准算法,而不是迭代器?

在非变异算法确实使用迭代器的情况下,它们都是根据*it定义的,可以分配给它需要分配给它的任何东西,或者对某些指定的操作或函数调用有效。我认为所有或大多数此类操作都没有价值。

我能想到的一件事是,你不能传递一个预期非const引用的值。是否存在需要非const引用的非变异算法?可能不是,只要任何函子参数等都有足够的const

很抱歉,我不能肯定地说没有奇怪的角落出错,但听起来对我来说基本没问题。即使有任何问题,您也可以通过算法版本与标准版本之间的要求略有不同来修复它们。

编辑:可能出错的第二件事是使用指针/引用并保持它们太长。据我所知,标准算法不保留指向元素的指针或引用 - 原因是它的容器保证了指向元素的指针的有效性,迭代器类型只告诉你什么时候 iterator 保持有效(例如,当原始递增时,输入迭代器的副本不一定保持有效,而对于多遍算法,可以以这种方式复制转发迭代器)。由于算法没有看到容器,只看到迭代器,所以我没有理由认为这些元素是持久的。

答案 3 :(得分:1)

由于您将“容器”放在“引号”中,您可以随心所欲。

STL类型的东西(迭代器,容器上的各种成员函数..)返回引用,因为引用是左值,并且某些构造(即myvec [i] = otherthing)可以编译。想想std :: map上的operator []。对于const引用,我想这不是一个避免复制的值。

虽然方便,但这条规则一直受到侵犯。迭代器类将当前值存储在成员变量中也是很常见的,仅仅是为了返回引用或const引用(是的,如果迭代器是高级的,则此引用将无效)。

如果你对这类东西感兴趣,你应该查看boost迭代器库。