首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将STL container<T *>转换为container<T const *>

将STL container<T *>转换为container<T const *>
EN

Stack Overflow用户
提问于 2013-03-12 11:23:41
回答 2查看 315关注 0票数 5

我正在寻找一种方法来制定一个课程:

  • 使用具有最大“恒定性”指针的STL容器的接口
  • 但是,它在内部对指向对象进行变异。
  • 与非const模拟相比,没有额外的运行时间开销。

理想情况下,与非const版本相比,解决方案不需要额外的代码,因为const/non ness只是对这里的程序员的一种帮助。

到目前为止,我尝试过的是:

代码语言:javascript
复制
#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_;
};

如果没有类型转换的解决方案,我想要关于如何构造具有所述属性的类的替代建议。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-03-12 11:46:33

让我们假设一下,您可以将list<T*>&转换为list<T const *>&。现在考虑以下代码:

代码语言:javascript
复制
list<char*> a;
list<char const*>& b = a;

b.push_back("foo");

a.front()[0] = 'x'; // oops mutating const data

T**转换为T const**也存在相同的概念问题。

如果您想提供对底层数据的只读访问,则需要提供它的一些自定义视图,可能需要使用自定义迭代器。

如下所示。

代码语言:javascript
复制
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;
}
票数 7
EN

Stack Overflow用户

发布于 2013-03-12 14:03:05

不要退回集装箱。返回迭代器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15359813

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档