我可以创建一个没有底层容器对象的空范围(迭代器对)吗?

Can I create an empty range (iterator pair) without an underlying container object?

我有一个 class 类似于以下内容:

struct Config
{
   using BindingContainer = std::map<ID, std::vector<Binding>>;
   using BindingIterator  = BindingContainer::mapped_type::const_iterator;

   boost::iterator_range<BindingIterator> bindings(ID id) const;
private:
   BindingContainer m_bindings;
};

由于传递给 bindings()ID 可能不存在,我需要能够在 return 类型域中表示一个 'no bindings' 值。

我不需要区分未知的 ID 和映射到空 vectorID,所以我希望能够通过界面实现这一点上面和 return 一个带有默认构造的迭代器的空范围。不幸的是,虽然 ForwardIteratorDefaultConstructible [C++11 24.2.5/1],但是比较单个迭代器的结果是未定义的 [24.2.1/5],所以没有容器看起来是这样的不可能。

我可以更改界面,例如将 iterator_range 包装在 boost::optional 中,或者将 return 包装在矢量值中;前者对于调用者来说有点笨重,而后者有不希望的复制开销。

另一种选择是保留静态分配的空向量和 return 它的迭代器。在这种情况下,开销不会有问题,但如果可以的话,我想避免它。

调整 map 迭代器以产生可比较的默认构造的迭代器是一种可能,尽管看起来过于复杂...

这里是否有任何其他选项可以在没有底层容器时支持 return空范围?

(顺便说一句,我确定前阵子我读过一篇工作论文或文章,内容是关于在没有容器对象时为标准容器类型生成空范围,但现在找不到任何内容。)

(请注意,我仅限于 C++11 功能,但如果有任何不同的方法需要更高版本的功能,我会很感兴趣。)

不,没有。您的选择如您所建议。就个人而言,我可能会采用从静态空向量中劫持迭代器对的想法;我无法想象这里会涉及什么名义上的 "overhead",除了过程映像中的几个额外字节。

  • Is this a singular iterator and, if so, can I compare it to another one?
  • Comparing default-constructed iterators with operator==

这在 C++14 或 C++17(到目前为止)中都没有改变。

您可以使用默认构造的boost::iterator_range

来自 (https://www.boost.org/doc/libs/1_55_0/libs/range/doc/html/range/reference/utilities/iterator_range.html):

However, if one creates a default constructed iterator_range, then one can still call all its member functions. This design decision avoids the iterator_range imposing limitations upon ranges of iterators that are not singular.

这里的例子: https://wandbox.org/permlink/zslaPwmk3lBI4Q9N