声明 'const' 'boost::range 's 的正确方式

Proper way of declaring `const` `boost::range`s

提问人:Anakhand 提问时间:3/22/2019 最后编辑:Anakhand 更新时间:3/24/2019 访问量:209

问:

使用 时,指定不应修改基础容器(如果有)的正确方法是什么?boost::any_range

例如,别名

template<typename T>
using Range = boost::any_range<T, boost::forward_traversal_tag>;

声明无法修改基础容器或“数据源”内容的范围(如果声明为

const Range<T> myRange;

或作为

Range<const T> myRange;

?

我怀疑第一个版本是正确的。但是,如果,例如,如果我应用任何 ?constboost::adaptors


编辑

文档中可以看出,显然元函数通过声明范围 而不是 .也就是说,is(如果基础容器具有此类成员类型)而不是 ,因此无法通过此迭代器修改容器。range_iteratorconstconst TTrange_iterator::<const T>::typeconst_iteratoriterator

这是否意味着它也用于遍历范围?Range<const T>const_iterators

C++ 升压 常量 boost-range

评论

1赞 Some programmer dude 3/22/2019
Range<const T>并且是两件截然不同的事情。第一个 () 是常数 的 。第二个 () 是非常数的常数。例如,这与以下两者的区别相同 和。const Range<T>Range<const T>RangeTconst Range<T>RangeTstd::vector<const int>const std::vector<int>
0赞 Anakhand 3/22/2019
@Someprogrammerdude 除了可能仍然能够修改底层容器之外,同时可以从元函数中推断出 ness(即使用 s 而不是 s)。那么,究竟什么是常数?一个使用或其“包装器”成员不更改(但底层容器可能会)?const Range<T>Range<const T>constconst_iteratoriteratorrange_iteratorRangeconst_iterators
0赞 Oktalist 3/22/2019
void f(const Range<T>)不会按照你的想法去做。请参阅顶级 const 不影响函数签名
0赞 Anakhand 3/22/2019
@Oktalist 是的,但这不是重点。我在问是否可以修改底层容器;我不是在问如何根据对象的 ness 重载函数---原则上它可以独立于底层容器的 ness。该函数只是一个示例。我会澄清的。const Range<T>Rangeconstconst
1赞 Davis Herring 3/23/2019
@Someprogrammerdude:不过,你实际上做不到。std::vector<const X>

答:

0赞 Anakhand 3/24/2019 #1

显然,确保值不被修改的正确方法都不是我提到的。

Boost.Range 的文档中,我们可以看到它采用了以下模板参数:any_range

template<
    class Value
  , class Traversal
  , class Reference
  , class Difference
  , class Buffer = any_iterator_default_buffer
>
class any_range;

我强烈怀疑声明“常量范围”的方法是指定为类型模板参数,尽管令人惊讶的是,我仍然无法在文档中找到任何明确的指示。const TReference

因此,常量范围可以声明为:

template<class C>
using ConstRange = boost::any_range<C, boost::forward_traversal_tag, const C, std::ptrdiff_t>