【问题标题】:C++ member template for boost ptr_vectorboost ptr_vector 的 C++ 成员模板
【发布时间】:2010-05-28 17:07:46
【问题描述】:

我正在尝试使用 boost::ptr_vector 编写一个容器类。在 ptr_vector 里面我想包含不同的类。我正在尝试使用静态模板来实现这一点,但到目前为止我还无法做到这一点。比如容器类是

class model {
private:
  boost::ptr_vector<elem_type> elements;
public:
  void insert_element(elem_type *a) {
element_list.push_back(a);
  }
};

我想要实现的是能够使用不同的 elem_type 类。下面的代码不能满足我的要求:

template <typename T>class model {
private:
  boost::ptr_vector<T> elements;
public:
  void insert_element(T *a) {
element_list.push_back(a);
  }
};

因为当我初始化容器类时,我只能使用一个类作为模板:

model <elem_type_1> model_thing;
model_thing.insert_element(new elem_type_1)

但不是 elem_type_2:

model_thing.insert_element(new elem_type_2)//error, of course

是否可以仅在成员上使用模板?

 class model {
private:
 template <typename T> boost::ptr_vector<T> elements;
public:
  void insert_element(T *a) {
element_list.push_back(a);
  }
}; //wrong

所以我可以在我想要插入的特定类上调用 insert_element 吗?请注意,我不想使用虚拟成员。 谢谢!

【问题讨论】:

  • 您收藏中的元素复制成本高吗?
  • 从集合中检索元素时,如何知道每个位置存储的元素类型?
  • 您的集合中可以存储的类型是否有限?或者可以存储任何东西?
  • 您好,埃米尔,感谢您的回复。这个想法是开发一个通用容器。我会事先知道应该存储什么类型,但我需要更改代码以便在开发新元素后立即扩展它们。这部分代码会被执行很多次,所以虚拟继承太慢了。访问元素时,我需要静态转换之类的东西。我将只在向量上插入一次,但会在执行期间按顺序读取整个列表多次。

标签: c++ templates boost stl


【解决方案1】:

尝试使用boost::variant的向量:

#include <iostream>
#include <vector>
#include <boost/variant.hpp>
#include <boost/foreach.hpp>

struct Foo
{
    Foo(int v=0) : a(v) {}
    int a;
};

struct Bar
{
    Bar(int v=0) : b(v) {}
    int b;
};

struct print_visitor : public boost::static_visitor<>
{
    void operator()(const Foo& foo) const
    {
        std::cout << "Foo " << foo.a << "\n";
    }

    void operator()(const Bar& bar) const
    {
        std::cout << "Bar " << bar.b << "\n";
    }
};

int main()
{
    typedef boost::variant<Foo, Bar> Variant;
    std::vector<Variant> bag;
    bag.push_back(Foo(123));
    bag.push_back(Bar(456));

    BOOST_FOREACH(const Variant& element, bag)
    {
        boost::apply_visitor(print_visitor(), element);
    }
}

boost::variant 的 apply_visitor 函数对于避免过度转换回原始类型很有用。

【讨论】:

    【解决方案2】:

    Vector 包含元素,其中每个元素都具有与其他元素相同的类型。如果要创建不同类元素的向量,可以使用 boost::any 类型的元素向量。

    【讨论】:

    • 使用 boost::any 时,我必须手动对 boost::ptr_vector 中的所有返回元素进行类型转换,这是不可取的。
    • @Ivan:据我所知,在 C++ 中,异构集合(即“包”)无法返回特定的非多态类型的元素(没有用户指定类型)。您可以选择返回对元素基类的引用(多态性)、使用变体类型(boost::any 或 boost::variant)、使用访问者模式或使用模板成员函数,其中模板参数指定返回类型。
    • 这对 C++ 来说是一个很大的缺点,因为它符合我的模拟的所有其他要求 - 速度、易于编码、易于维护。我将使用您提供的代码使用变体和访问者以及用于访问的函子进行一些测试。但是,如果这显示有问题,使用相同的方法并使用 Fortran 可能更容易吗?速度是一个非常重要的因素,只有精度更重要。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-30
    • 1970-01-01
    • 2014-01-30
    • 1970-01-01
    • 1970-01-01
    • 2020-08-22
    • 1970-01-01
    相关资源
    最近更新 更多