Dreamer
Dreamer

Reputation: 582

C++ Error: no match for call to ‘(std::string {aka std::basic_string<char>}) (std::string&)’

I'm new to C++. I search many times, but still can't get the answer. I'm writing a class named Course to describe the courses students taking at school. The Course class has 3 fileds:

protected:
    string courseName;
    int courseNum;
    float score; 

And I have a public method "setName" to set the course name:

Course &setName(string name)
{
    this->courseName(name);
    return (*this);
}

However, when I tried to compile, the compiler complains that: C++ Error: no match for call to ‘(std::string {aka std::basic_string}) (std::string&)’ I also tried to modify the code to Course &setName(string &name)... And the compiler keeps complaining about the same error.

But if I change the code to:

Course &setName(string name)
{
    this->courseName = name;
    return (*this);
}

Then it works well. I couldn't understand what the compiler is complaining about and why I can't use the direct initialization?

Upvotes: 5

Views: 34742

Answers (2)

juanchopanza
juanchopanza

Reputation: 227420

You are attempting to assign the value of one string to another, which has already been initialized. The syntax for that is

std::string s1 = ....;
std::string s2 = ....;
s2 = s1; // OK, assignment

whereas you are attempting the equivalent of

s2(s1); // error, this is no way to assign s1 to s2

and that is just invalid syntactically in this context. You cannot initialize objects that have already been constructed.

Upvotes: 2

Andy Prowl
Andy Prowl

Reputation: 126432

I couldn't understand what the compiler is complaining about and why I can't use the direct initialization?

Because that's not an initialization. That's an assignment. Both assignment an (copy-)initialization make use of the = sign, but don't let that fool you: the two things are fundamentally different.

Initialization is what gives a value to an object upon construction. When your setName() member function gets called, the object on which it is invoked (as well as its data members) have already been constructed. If you want to initialize them there, you're late: you've missed the train.

In a constructor's initialization list, on the other hand, you could initialize your data members as follows:

Course::Course(std::string name) : courseName(std::move(name)) { }
//                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^
//                                 This would be initialization

Upvotes: 6

Related Questions