使用指针,我可以为任何类型T创建(const/non_const)到(T/const T)的所有组合,如this answer中详细讨论的那样。
但是使用引用时,我如何定义一个对一个可以被解引用的变量的引用(像迭代器一样),这样解引用的引用就给出了一个常量访问?
例如,考虑以下程序:
#include <array>
int main()
{
std::array<int, 3> a{0, 0, 0};
auto const& iter = a.begin();
// iter++; // Error!
(*iter)++;
}
iter
是const
变量,如果取消注解iter++
行,代码将无法编译。但是iter
解引用了一个非常数的int,实际上它可以随(*iter)++
递增。在某种意义上,iter
模拟int * const
,即指向int的常量指针。
是否可以使用(const或non_const)引用iter
,使*iter
成为const int?
请记住,我知道我可以在上面的例子中使用const auto& iter = a.cbegin()
,这个问题的目的是如何定义iter
,这样,当解引用时,不管等号右边是什么,都可以给一个常量访问,对于迭代器,我可以想象显式绑定到const_iterator
,如下所示:
const decltype(a)::const_iterator& iter = a.begin();
这个解决方案之所以有效,是因为我知道iterator
的等效"常量访问"是const_iterator
。
但是,更一般地说:
(some type)& iter = rhs
如果我只知道*rhs
是一个int,那么有没有可能找出iter的类型,使得*iter
是一个const int?
值得考虑的另一点是rhs
转换的可能成本。
2条答案
按热度按时间3bygqnnd1#
是否可以使用(
const
或非const
)引用iter
,以使*iter
成为const int
?你调用
std::array::cbegin()
成员函数,它将返回一个std::array<int, 3>::const_iterator
.解引用,它将给予你一个const int&
。const
引用来获取const_iterator
,你必须通过值或const&
来获取它(以延长由cbegin()
函数返回的临时变量的生命期),一般的建议是通过值来获取迭代器。有没有可能找出
iter
的类型,使得*iter
是const int
?如果你 * 知道 *
iter
是某种指针(const T*
,const T*&
,T*
或T*&
等),那么你可以得到一个const T*
,如下所示:对于一般情况,从
iterator
获取const_iterator
,而不使用容器的typedef
作为const_iterator
,将有点麻烦。一种方法是将迭代器 Package 在一个interator类中,该类在解引用时只返回const&
。下面是一个std::list<int>::iterator
的示例,它比指针稍微复杂一些。不过它对指针也有效。yvgpqqbh2#
这个问题的目的是如何定义
iter
,以便在取消引用时给予常量访问这就是const迭代器发挥作用的地方,对于迭代器来说,这实际上是一个不太全局的问题,因为const迭代器仅仅意味着一个常量容器的标准迭代器:
在这种情况下,迭代器自身类型的一致性实际上并不取决于它们是否指向const类型,正如你已经注意到的,
const
迭代器意味着迭代器本身不能被改变,不能指向不同的对象。回答你的第二个问题:
是否可以改为使用(const或non_const)引用const int?
不,引用总是
const
隐式的,并且在绑定到变量之后不能被重新绑定。