C ++集合类调用子函数

时间:2011-09-22 13:51:27

标签: c++ templates

我正在研究的项目有一些非常讨厌的集合类,我觉得可以使用重新设计。我真的很想创建一个收集模板实例的集合模板类,并提供一种方法来调用集合中每个子类的特定于类型的函数。例如,像:

MyCollection<Student> BiologyStudents();
// [Fill the collection]
BiologyStudents.EnrollInClass(ClassList::Biology);
BiologyStudents.Commit();

我的想法是,我可以使用我的集合轻松地将所有学生注册到课程中,然后将这些更改提交到数据库。我的问题是如何公开属于子学生对象的EnrollInClass()函数?如果我的集合包含与Student不同类型的对象,我希望这些函数从集合中公开。我能想到用我的半有限C ++知识来做这件事的唯一方法是创建一个函数,该函数接受一个参数,该参数引用我知道的函数在包含的子类中。如果您调用错误的函数或提供错误的参数,这将不会提供编译错误,因此我想要一种利用编译器提供这些检查的方法。

这可能吗?如果是这样,怎么样?作为一个警告,我已经习惯了Java / C#中的泛型编程,所以我对C ++模板的印象可能有些偏差。

1 个答案:

答案 0 :(得分:2)

一种方法是使用方法指针:

template <typename T>
struct MyCollection {
  template <typename U>
  void ForEach(void (T::*func)(U),U param)
  {
    // for each item loop goes here
    (item.*func)(param);
  }
};


MyCollection<Student> BiologyStudents;
// [Fill the collection]
BiologyStudents.ForEach(&Student::EnrollInClass,ClassList::Biology);

您必须为不同数量的参数提供不同的版本。

使用C ++ 11,您可以这样做:

template <typename T>
struct MyCollection {
  void ForEach(std::function<void (T &)> func)
  {
    // for each item loop goes here
    func(item);
  }
};


MyCollection<Student> BiologyStudents;
// [Fill the collection]
BiologyStudents.ForEach([](Student &s){s.EnrollInClass(ClassList::Biology);});

不需要为不同数量的参数制作不同版本的ForEach。