我正在研究的项目有一些非常讨厌的集合类,我觉得可以使用重新设计。我真的很想创建一个收集模板实例的集合模板类,并提供一种方法来调用集合中每个子类的特定于类型的函数。例如,像:
MyCollection<Student> BiologyStudents();
// [Fill the collection]
BiologyStudents.EnrollInClass(ClassList::Biology);
BiologyStudents.Commit();
我的想法是,我可以使用我的集合轻松地将所有学生注册到课程中,然后将这些更改提交到数据库。我的问题是如何公开属于子学生对象的EnrollInClass()
函数?如果我的集合包含与Student不同类型的对象,我希望这些函数从集合中公开。我能想到用我的半有限C ++知识来做这件事的唯一方法是创建一个函数,该函数接受一个参数,该参数引用我知道的函数在包含的子类中。如果您调用错误的函数或提供错误的参数,这将不会提供编译错误,因此我想要一种利用编译器提供这些检查的方法。
这可能吗?如果是这样,怎么样?作为一个警告,我已经习惯了Java / C#中的泛型编程,所以我对C ++模板的印象可能有些偏差。
答案 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。