开发者

C++ collection class to call children functions

The project I'm working on has some pretty nasty collection classes that I feel could use a redesign. I'd really like to make a collection template class that takes model instances and provides a way to call type-specific functions of each child in the collection. For example, something like:

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

The idea is that I could easily enroll all students in a class using my collection, then commit those changes to a database. My problem is in how to expose that EnrollInClass() function which belongs to the children Student objects? If my collection contains objects of a different type than Student, I would like those functions to be exposed from the collection. The only way I can think to do that with my semi-limited C++ knowledge would be to make a f开发者_C百科unction that takes a parameter which references a function I know is in the containing child class. This wouldn't provide compilation errors if you call the wrong function or provide the wrong parameters, so I'd like a way to utilize the compiler to provide these checks.

Is this possible? If so, how? As a warning, I'm used to generic programming in Java/C#, so my impression of C++ templates might be a bit off.


One way would be to use a method pointer:

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

You would have to provide different versions for different numbers of parameters.

With C++11, you can do this:

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

Which would not require making different versions of ForEach for different numbers of parameters.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜