【问题标题】:Conversion between std::vector subclass with custom allocator and std::vectors带有自定义分配器的 std::vector 子类和 std::vectors 之间的转换
【发布时间】:2012-10-17 14:32:08
【问题描述】:

我有一个高级 C++ 问题:假设我有一个 mmap_allocator 模板类,它是 std::allocator 模板的子类 类和一个 mmappable_vector 模板类,它是一个子类 std::vector 模板类的:

    template <typename T>
    class mmap_allocator: public std::allocator<T> {
            ...
    };

    template <typename T, typename A = mmap_allocator<T> >
    class mmappable_vector: public std::vector<T, A> {
            ...
    };

我能做的是从 mmappable_vector 转换(使用 mmap_allocator) 使用函数模板到 std::vector(使用标准分配器):

    template <typename T>
    std::vector<T> to_std_vector(const mmappable_vector<T> &v)
    {
            return std::vector<T>(v.begin(), v.end());
    }

但另一种方式似乎是不可能的:

    template <typename T>
    mmappable_vector<T> to_mmappable_vector(const std::vector<T> &v)
    {
            return mmappable_vector<T>(v.begin(), v.end());
    }

定义构造函数时遇到的问题:

    typedef typename std::vector<T, A>::iterator iterator;

    mmappable_vector(iterator from, iterator to):
                    std::vector<T,A>(from, to)
    {
    }

这将迭代器与 mmap_allocator 一起使用,因此不匹配 to_mmappable_vector 中的调用。另一方面定义一个 构造函数:

    mmappable_vector(std::vector<T,std::allocator<T> > v):
            std::vector<T,std::allocator<T> >(v)
    {
    }

失败是因为

    std::vector<T,std::allocator<T> > 

不是 mmappable 向量的基类。

如何编写将 std::vectors 转换为的函数模板 mmappable_vectors?这在 C++ 中是否可行?

感谢您的任何见解,

  • 约翰内斯

【问题讨论】:

  • 查找带有一对迭代器的向量构造函数。它不需要 vector::iterators,它需要 any 个迭代器。

标签: c++ templates constructor subclassing allocator


【解决方案1】:

mmappable_vector 中没有模板构造函数,它接受两个任意类型的迭代器。喜欢这个:

template <typename T, typename A = mmap_allocator<T> >
    class mmappable_vector: public std::vector<T, A> {
      typedef std::vector<T, A> Base;
      ...

      template <typename Iter>
      mmappable_vector(Iter first, Iter last, A a = A()) : Base(begin, end, a) {}

};

http://www.sgi.com/tech/stl/stl_vector.h


但更重要的是你根本不应该这样定义你的向量:

template <typename T, typename A = mmap_allocator<T> >
    class mmappable_vector: public std::vector<T, A> {
            ...
    };

这是错误的,因为它派生自 STL 容器,派生是公共的,并且您没有虚拟析构函数。


据我了解您的问题 - 您只需要一个 typedef。 C++中typedef的制作方式有两种——C++11和C++03方式:

C++11

template< typename T, typename A = mmap_allocator<T> >
using mmappable_vector = std::vector<T, A>;

C++03

    template <typename T, typename A = mmap_allocator<T> >
    struct mmappable_vector {
        typedef std::vector<T, A> type;
    };

将其用作:

    mmappable_vector<int>::type

【讨论】:

  • 感谢您的回答。据我了解,我需要 std::vector 子类,因为我必须添加一个修改 std::vector 类的受保护属性的方法 (mmap_file())。我在这种方法中所做的是在不初始化内容的情况下设置向量的大小。 mmappable_vector 的内容直接来自 mmapped 文件,据我所知,没有其他方法可以实现这一点。至于析构函数,我在 mmappable_vector 类中没有任何要销毁的东西,并使用 std::vector 的析构函数(在分配器上调用 deallocate)。
  • 请参阅github.com/johannesthoma/mmap_allocator 获取完整源代码,如果您能改进它,我将不胜感激。如何编写接受任何类型迭代器的构造函数(对不起这个愚蠢的问题..)。 std::vector::iterator 的构造函数不能重载,对于 mmappable_vector 也无济于事,因为 to_mmappable_vector() 中的迭代器属于 std::vector::iterator 类型。
  • @JohannesThoma 查看更新。你只需要模板构造函数。
  • 非常感谢,我从没想过在模板中有一个模板 .. 它可以编译并且现在似乎可以工作了。
猜你喜欢
  • 1970-01-01
  • 2012-08-07
  • 2011-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-04
  • 1970-01-01
相关资源
最近更新 更多