5

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?

1
  • The first example is trying to invoke a function call operator. std::string does not declare this operator which results in the error you are receiving. Commented Jun 23, 2013 at 17:07

2 Answers 2

6

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
Sign up to request clarification or add additional context in comments.

5 Comments

Oh, thank you, I see where the problem is. I don't quite understand if "string str = "hello" " is another kind of initialization? Can the =operator be used to do initialization?
@Dreamer: When the = sign appears in the context of a declaration, then you have initialization. So for instance string str = "hello" is an initialization - pretty much like string str("Hello") - because it's in the context of the declaration of str. However, str = "hello" is an assignment, since you're not declaring a new variable here.
I see the difference. Does string str = "hello" equals to: first, do default initialization string str() then do the copy assignment str = "hello"?
@Dreamer: Nope. As I wrote in the previous comment, string str="hello" is the same as string str("hello"). Default initialization + assignment would be: string str; str = "hello".
@AndyProwl: Actually, string str="hello" is the same as string str(string("hello")) — while for string it won't make a difference (the extra copy will be optimized away anyway), it does for classes where the copy constructor does not exist/is not accessible.
2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.