Variable is not a type

#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Course
{
    public:
        string name;
        string instructorInCharge;
        int numberOfStudents;
        int totalMarks;
        Course(string u, string v, int p, int q){
            this->name=u;
            this->instructorInCharge=v;
            this->numberOfStudents=p;
            this->totalMarks=q;

        }
    
    vector<int> studentMarks (numberOfStudents);

    

};
class Labs:public Course
{
   
        vector<int>labMarks(numberOfStudents);

};

int main()
{
    Course c("Rahul","Hota",200,300);
    cout<<"hello there";
}

When I compile this code I’m getting the following error:

1.cpp:20:31: error: 'numberOfStudents' is not a type
   20 |     vector<int> studentMarks (numberOfStudents);
      |                               ^~~~~~~~~~~~~~~~
1.cpp:28:29: error: 'numberOfStudents' is not a type
   28 |         vector<int>labMarks(numberOfStudents);
      |                             ^~~~~~~~~~~~~~~~

Please tell me what my mistake is. numberostudents was supposed to be the size of the vector. But not any function.


Solution 1:

vector<int> studentMarks (numberOfStudents);

This is a function declaration. The return type is vector<int>, the name is studentMarks and it accepts a single parameter of type numberOfStudents. Except, as the error points out, numberOfStudents is not a type.

You cannot use parentheses to specify a default member initialiser. You have to either use curly braces:

T member {value};

or "equals" initialiser:

T member = value;

Note however, that you don't initialise numberOfStudents member, but rather assign it later in the constructor body. This assignment is after studentMarks has been initialised, and thus the default member initialiser of studentMarks won't reflect the size that was assigned. Rather, the behaviour of the program would be undefined due to the use of an indeterminate value. This can be fixed by initialising numberOfStudents in the member initialiser list.

Solution 2:

If you want in-class initialization, you may do this:

vector<int> studentMarks = vector<int>(numberOfStudents);

Now the default constructor will initialize studentMarks with vector<int>(numberOfStudents) when an instance of Course is created.

However, this will cause undefined behavior since numberOfStudents is not initialized before the initialization of studentMarks. You could use the member initalizer list instead:

Course(std::string u, std::string v, int p, int q)
    : name(std::move(u)),
      instructorInCharge(std::move(v)),
      numberOfStudents(p),
      totalMarks(q),
      studentMarks(numberOfStudents)
{
}

and likewise for the Labs class:

class Labs : public Course {
public:
    Labs(std::string u, std::string v, int p, int q)
        : Course(u, v, p, q),  // initialize the base class part of a `Labs`
          labMarks(p)          // initialize the added member variable
    {
    }
    std::vector<int> labMarks;
};