类构造函数问题中的简单可变模板

时间:2019-01-06 14:38:18

标签: c++ constructor variadic-templates

我是一位C ++初学者,试图实现Course类,该类具有stl unordered_map作为成员变量来存储学生的成绩。

#include <iostream>
using namespace std;

class Course{

    string course_name;
    Supervisor PI;
    Teacher TA;
    unordered_map<Student, int> grades;

public:

    Course(string name, 
    void get_student_grade(Student person){
        return grades. ;
    }
    void printGrades(){
        return ;
    }
};

class Student{

string name;

public:

    Student(string namee):name(namee){}
};

int main(){

    Course calculus{"calculus", Student Matt("Matt"), Student James("James"), 
        Student Michelle("Michelle"), Student Ashley("Ashley"), Student Karen("Karen")};

    calculus.printGrades(); 
}

我正在尝试创建一个课程构造器,该构造器采用课程字符串和任意数量的学生对象参数并将其存储在unordered_map中。

到目前为止,谷歌已经教给我一种叫做可变参数模板的东西,它可以启用任意数量的参数,但是在我的情况下,我似乎还不知道如何应用该参数。另外,是否可以将Student对象存储为unordered_map的键?我的意思是说当我做某事

return grades[James];

,哈希表将搜索字符串James,然后返回值。

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

仅当不需要齐列表时(或在某些其他极少数情况下必须移动类型),才应使用可变参数模板。就您而言,std::initializer_list就足够了。

这是两种方法(创建课程时请注意缺少的花括号)。在一个类中同时使用这两种实现是一个坏主意,这只是为了演示。

class Course {
  std::string course_name;
  std::unordered_map<Student, int> grades;

 public:
  Course(std::string name, std::initializer_list<Student> students) {
    for (const auto& s : students) grades[s] = 0;
  }

  template <typename... Students>
  Course(std::string, Students&&... students) {
    ((grades[std::forward<Students>(students)] = 0), ...);
  }
};

int main() { 
  Course initializer{"calculus", {Student{"Matt"}, Student{"James"}}}; 
  Course variadic{"calculus", Student{"Matt"}, Student{"James"}};
}

您必须提供比较运算符和哈希函数,才能使用Student作为键。提供散列函数的方法有多种,此版本专门用于STL实现。

class Student {
 public:
  Student(std::string namee) : name(namee) {}
  bool operator==(const Student& other) const { return name == other.name; }
  std::string name;
};

namespace std {
template <>
struct hash<Student> {
  size_t operator()(const Student& s) const {
    return std::hash<std::string>()(s.name);
  }
};
}  // namespace std

请注意,为方便起见,我公开了name