转换 STL 容器&lt;T *&gt;到容器<T const *> [英] Converting STL container&lt;T *&gt; to container&lt;T const *&gt;

查看:53
本文介绍了转换 STL 容器&lt;T *&gt;到容器<T const *>的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找一种方法来制定一个具有以下内容的类:

I'm looking for a way to formulate a class having:

  • 使用 STL 指针容器的接口,具有最大的一致性"
  • 但是它在内部改变了指向的对象
  • 与非常量模拟相比没有额外的运行时开销

理想情况下,与非常量版本相比,该解决方案不会编译为任何额外代码,因为常量/非常量性只是对程序员的一种帮助.

Ideally, the solution would compile to no extra code compared to the non-const version since const/non-const-ness is just an aid to programmers here.

这是我迄今为止尝试过的:

Here's what I've tried so far:

#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_;
};

如果没有类型转换的解决方案,我想就如何制定具有所描述属性的类提供替代建议.

If there is no solution to the type conversion, I'd like alternative suggestions on how to formulate a class having the properties described.

推荐答案

让我们假设您可以将 list& 转换为 list.现在考虑以下代码:

Let us assume for a moment you can convert list<T*>& to list<T const *>&. Now consider the following code:

list<char*> a;
list<char const*>& b = a;

b.push_back("foo");

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

与将 T** 转换为 T const** 的概念问题相同.

It's the same conceptual problem with converting T** to T const**.

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

If you want to provide readonly access to the underlying data, you will need to provide some custom view of it, possibly using custom iterators.

类似于以下内容.

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;
}

这篇关于转换 STL 容器&lt;T *&gt;到容器<T const *>的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆