Вы должны использовать шаблоны переменных только тогда, когда вам не нужны однородные списки (или в некоторых других редких случаях, когда типы должны быть перемещены). В вашем случае 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
публичным для удобства.