STL Push_back string in vector

1.5k Views Asked by At

I am trying to push a string in a string vector, like below

void Node::set_val(string &val)
{
    this->val.push_back(val);
}

But when I try to call it as below

Obj.set_val("10h;");

I get the below error,

error: no matching function for call to 'Node::set_val(const char [5])'

I assumed that the string in " " is same as string in c++, Why do I get such an error? What has to be changed below?

3

There are 3 best solutions below

0
On BEST ANSWER

You are taking in a std::string by non-const reference. Non-const references cannot bind to rvalues, like "10h;", so you can't pass literals in to that function.

If you aren't going to modify the argument, you should take your argument by reference-to-const:

void Node::set_val(const string &val)
//                 ^^^^^

This way, a temporary std::string will be constructed from your const char[5] and passed in to set_val.

You could improve this by taking in the string by value and moveing it into the vector:

void Node::set_val(string val)
{
    this->val.push_back(std::move(val));
}

This prevents you from making some unnecessary copies.

0
On

You are passing "10h;" which is a const char array.

Fix it by passing a string: Obj.set_val(string("10h")); and edit function to take a string by value:

void Node::set_val(string val) { /* */ }

Or maybe better, edit your function to take a const string&:

void Node::set_val(const string &val) { /* */ }
2
On

So in C++, const char* is implicitly convertible to std::string because std::string has a (non-explicit) constructor that takes const char*. So what the compiler tries here is to create a temporary std::string object for your function call, like so:

Node.set_val(std::string("10h;"));

However, since you declared the parameter of set_val to be a non-const reference to a std::string, the compiler can't make this conversion work due to the fact that temporary objects can't be bound to non-const references.

There are three ways to make this work, depending on what you want to achieve:

void Node::set_val(const std::string& val) {}
void Node::set_val(std::string val) {}
void Node::set_val(std::string&& val) {}

All will compile (the last one requires C++11 or higher), but seeing your use case, I would recommend to use the second or third one. For an explanation why, try reading a little bit about move semantics in C++11.

The important thing to take away here is that const char* implicitly converts to std::string by creating a temporary object, and temporary objects can't be passed to functions taking non-const references.