[英]std::upper_bound returns const iterator in const member function
Here is a class that contains a boost::circular_buffer
of some struct
. 这是一个包含某些
struct
的boost::circular_buffer
的类。 I make a typedef for iterators into the contained circular_buffer
. 我为迭代器创建了一个typedef到包含的
circular_buffer
。
My problem is this: when the doWork
function is marked const
, the returned value of std::upper_bound
is not compatible with the MyIterator
type due to the return value having boost::cb_details::const_traits
. 我的问题是:当
doWork
函数标记为const
,由于返回值为boost::cb_details::const_traits
,因此std::upper_bound
的返回值与MyIterator
类型不兼容。 If I remove the const
keyword from the function, all my compile errors go away. 如果我从函数中删除
const
关键字,我的所有编译错误都会消失。
To be clear the compiler error is this: 要清楚编译器错误是这样的:
error: conversion from 'boost::cb_details::iterator<boost::circular_buffer<Wrapper<int>::Sample, std::allocator<Wrapper<int>::Sample> >, boost::cb_details::const_traits<std::allocator<Wrapper<int>::Sample> > >' to non-scalar type 'Wrapper<int>::MyIterator {aka boost::cb_details::iterator<boost::circular_buffer<Wrapper<int>::Sample, std::allocator<Wrapper<int>::Sample> >, boost::cb_details::nonconst_traits<std::allocator<Wrapper<int>::Sample> > >}' requested [](const Sample& a, const Sample& b) { return a.foo < b.foo; });
Here is a self-contained example: 这是一个独立的例子:
#include <algorithm>
#include <boost/circular_buffer.hpp>
template <typename T>
class Wrapper {
public:
struct Sample {
T foo;
};
typedef typename boost::circular_buffer<Sample>::iterator MyIterator;
Wrapper(int size) { cb.resize(size); }
void add(T val) { cb.push_back(Sample{val}); }
void doWork(T bound) const {
MyIterator iter =
std::upper_bound(cb.begin(), cb.end(), Sample{3},
[](const Sample& a, const Sample& b) { return a.foo < b.foo; });
}
boost::circular_buffer<Sample> cb;
};
int main() {
Wrapper<int> buf(100);
buf.add(1);
buf.add(5);
buf.doWork(3);
return 0;
}
So, why can't this function be const? 那么,为什么这个函数不能是const? Why does marking it const have this side-effect?
为什么标记为const会产生这种副作用? I want a non-const iterator into the container, but in my real test case I don't intend to actually modify the container at all.
我想在容器中使用非const迭代器,但在我的实际测试用例中,我并不打算实际修改容器。
You're going to need a const_iterator
, since you're effectively observing a const
container. 你需要一个
const_iterator
,因为你有效地观察了一个const
容器。
Perhaps: 也许:
typedef typename boost::circular_buffer<Sample>::const_iterator MyConstIterator;
… then make iter
one of these. ...然后让
iter
其中之一。
Someone's going to tell you that you could have avoided this with auto
. 有人会告诉你,你可以用
auto
来避免这种情况。 That's true, but then you never would have discovered this "bug", or that const_iterator
s exist. 这是真的,但是你永远不会发现这个“bug”,或者
const_iterator
存在。
If your function is marked const
then all your access to member variables will be const
too. 如果您的函数标记为
const
那么您对成员变量的所有访问权限也将是const
。
A const
container will only allow access to const_
iterators, that's just the way iterators work. const
容器只允许访问const_
迭代器,这就是迭代器的工作方式。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.