C++ 只为容器提供常量迭代器有意义吗?
我有一个类似于下一个的容器:C++ 只为容器提供常量迭代器有意义吗?,c++,c++11,iterator,C++,C++11,Iterator,我有一个类似于下一个的容器: class MySpecialContainer { std::vector<std::tuple<InternalType, Type1, Type2>> _vec; }; 正如您所看到的,这种方法有几个限制,比如不能在子范围上迭代,或者不能使用非变异std::algorithms 考虑到MySpecialContainer元素从外部是不可变的,从逻辑上考虑,只为其提供const\u迭代器有意义吗 如果第一个问题的答案是肯定的,那
class MySpecialContainer
{
std::vector<std::tuple<InternalType, Type1, Type2>> _vec;
};
正如您所看到的,这种方法有几个限制,比如不能在子范围上迭代,或者不能使用非变异std::algorithms
考虑到MySpecialContainer
元素从外部是不可变的,从逻辑上考虑,只为其提供const\u迭代器有意义吗
如果第一个问题的答案是肯定的,那么最好是
将\u vec
分为两个容器,一个用于InternalType
,另一个用于std::pair
,保持它们同步,只需返回第二个向量的常量迭代器即可
保持向量现在的状态,并创建一个自定义迭代器,该迭代器仅公开consttype1
和consttype2
一种选择是公开迭代器,该迭代器只允许访问元素的某些字段,例如:
#include <vector>
#include <tuple>
#include <boost/iterator/transform_iterator.hpp>
struct Type1 {};
struct Type2 {};
struct InternalType {};
class MySpecialContainer
{
typedef std::vector<std::tuple<InternalType, Type1, Type2>> Vec;
Vec _vec;
struct Extractor
{
std::tuple<Type1&, Type2&> operator()(Vec::value_type& t) const {
return std::tie(std::get<1>(t), std::get<2>(t));
}
std::tuple<Type1 const&, Type2 const&> operator()(Vec::value_type const& t) const {
return std::tie(std::get<1>(t), std::get<2>(t));
}
};
public:
typedef boost::transform_iterator<Extractor, Vec::iterator> iterator;
typedef boost::transform_iterator<Extractor, Vec::const_iterator> const_iterator;
iterator begin() { return iterator{_vec.begin()}; }
iterator end() { return iterator{_vec.end()}; }
const_iterator begin() const { return const_iterator{_vec.begin()}; }
const_iterator end() const { return const_iterator{_vec.end()}; }
};
int main() {
MySpecialContainer c;
for(auto x : c) {
}
}
#包括
#包括
#包括
结构类型1{};
结构类型2{};
结构内部类型{};
类MySpecialContainer
{
typedef std::向量向量;
Vec(u-Vec),;
结构提取器
{
std::tuple operator()(Vec::value\u type&t)常量{
返回std::tie(std::get(t),std::get(t));
}
std::tuple operator()(Vec::value_type const&t)const{
返回std::tie(std::get(t),std::get(t));
}
};
公众:
typedef boost::transform_迭代器迭代器;
typedef boost::transform_iterator const_iterator;
迭代器begin(){返回迭代器{u vec.begin()};}
迭代器end(){返回迭代器{u vec.end()};}
常量迭代器begin()常量{返回常量迭代器{vec.begin()};}
常量迭代器end()常量{返回常量迭代器{u vec.end()};}
};
int main(){
我的特殊容器c;
用于(自动x:c){
}
}
请注意,通过非常量迭代器,您仍然可以更新公开的值,因为trasform迭代器返回一个引用元组。只公开常量迭代器就可以了。标准中甚至有优先权,因为std::set
有效地做到了这一点。从技术上讲,iterator
和const\u iterator
可以是不同的类型,但是不允许通过任何一种类型的迭代器修改元素,因为这可能会破坏集的不变量
使用合适的类而不是元组
(因此您可以通过访问者公开Type1
,Type2
)@Jarod42第二个问题的解决方案非常好!谢谢!@Felics回答你的第一个问题,是的,当你想防止类外的修改时,为封装的向量提供常量迭代器是最简单的解决方案。作为一个额外的奖励,只允许返回常量迭代器,你正在传达你对membe的意图r也是。在标准库中是否有一个等价的boost::transform\u iterator
呢?@Felics-Nope,标准库非常简单。这就是boost存在的原因……你可以派生std::vector::iterator
并重写操作符*
和操作符->
来进行转换。谢谢!我会投票给你r回答,因为这是一种关于如何提供迭代器的非常有趣的方法。我不会接受它,因为它没有回答我关于只提供const_迭代器
@Felics的问题。好吧,您可以省略begin/end的非const版本。它们在这里展示,可以为您的元素的某些成员提供可修改的视图这是第一个问题的答案,第二个问题的答案请查看Maxim Yegorushkin的答案。
#include <vector>
#include <tuple>
#include <boost/iterator/transform_iterator.hpp>
struct Type1 {};
struct Type2 {};
struct InternalType {};
class MySpecialContainer
{
typedef std::vector<std::tuple<InternalType, Type1, Type2>> Vec;
Vec _vec;
struct Extractor
{
std::tuple<Type1&, Type2&> operator()(Vec::value_type& t) const {
return std::tie(std::get<1>(t), std::get<2>(t));
}
std::tuple<Type1 const&, Type2 const&> operator()(Vec::value_type const& t) const {
return std::tie(std::get<1>(t), std::get<2>(t));
}
};
public:
typedef boost::transform_iterator<Extractor, Vec::iterator> iterator;
typedef boost::transform_iterator<Extractor, Vec::const_iterator> const_iterator;
iterator begin() { return iterator{_vec.begin()}; }
iterator end() { return iterator{_vec.end()}; }
const_iterator begin() const { return const_iterator{_vec.begin()}; }
const_iterator end() const { return const_iterator{_vec.end()}; }
};
int main() {
MySpecialContainer c;
for(auto x : c) {
}
}