我正在寻找一种方法来制定具有以下内容的课程:
- 使用具有最大“常量”的指针的 STL 容器的接口
- 但它会在内部改变所指向的对象
- 与非常量模拟相比,没有额外的运行时开销
理想情况下,与非常量版本相比,该解决方案不会编译为额外的代码,因为常量/非常量性只是对程序员的帮助。
到目前为止,这是我尝试过的:
#include <list>
#include <algorithm>
using namespace std;
typedef int T;
class C
{
public:
// Elements pointed to are mutable, list is not, 'this' is not - compiles OK
list<T *> const & get_t_list() const { return t_list_; }
// Neither elements nor list nor' this' are mutable - doesn't compile
list<T const *> const & get_t_list2() const { return t_list_; }
// Sanity check: T const * is the problem - doesn't compile
list<T const *> & get_t_list3() { return t_list_; }
// Elements pointed to are immutable, 'this' and this->t_list_ are
// also immutable - Compiles OK, but actually burns some CPU cycles
list<T const *> get_t_list4() const {
return list<T const *>( t_list_.begin() , t_list_.end() );
}
private:
list<T *> t_list_;
};
如果没有类型转换的解决方案,我希望获得有关如何制定具有所描述属性的类的替代建议。
让我们假设您可以转换list<T*>&
to list<T const *>&
。现在考虑以下代码:
list<char*> a;
list<char const*>& b = a;
b.push_back("foo");
a.front()[0] = 'x'; // oops mutating const data
这与转换是同样的概念问题T**
to T const**
.
如果您想提供对底层数据的只读访问,您将需要提供一些自定义视图,可能使用自定义迭代器。
像下面这样的东西。
template <typename It>
class const_const_iterator {
private:
using underlying_value_type = typename std::iterator_traits<It>::value_type;
static_assert(std::is_pointer<underlying_value_type>(),
"must be an iterator to a pointer");
using pointerless_value_type = typename std::remove_pointer<underlying_value_type>::type;
public:
const_const_iterator(It it) : it(it) {}
using value_type = pointerless_value_type const*;
value_type operator*() const {
return *it; // *it is a T*, but we return a T const*,
// converted implicitly
// also note that it is not assignable
}
// rest of iterator implementation here
// boost::iterator_facade may be of help
private:
It it;
};
template <typename Container>
class const_const_view {
private:
using container_iterator = typename Container::iterator;
public:
using const_iterator = const_const_iterator<container_iterator>;
using iterator = const_iterator;
const_const_view(Container const& container) : container(&container) {}
const_iterator begin() const { return iterator(container->begin()); }
const_iterator end() const { return iterator(container->end()); }
private:
Container const* container;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)