1

I have a code that compiles, and it looks like:

    void test1(const std::string &name)................
    test1("myName");

But, if I remove the const from the declaration as:

    void test2(std::string &name)................
    test2("myName");

The code just doesn't compile.

Why the const std::string makes it compile? As far as I understand the same implicit constructor will be called for the char * to be converted to a std::string.

I am using Visual Studio 2013, in case this might be related to the answer.

Michel Feinstein
  • 13,416
  • 16
  • 91
  • 173

4 Answers4

5

When the implicit conversion happens, you get a temporary std::string (technically, the important thing is that it is an xvalue). You cannot bind a temporary to a lvalue reference std::string & but you can bind to a const lvalue reference const std::string & or an rvalue reference std::string &&.

The same thing happens here:

const int &x = 5;
int &x = 5; // error
Dietrich Epp
  • 205,541
  • 37
  • 345
  • 415
2

You get an error in second case because a temporary can not bind to a non-const reference.

test("myName"); tries to bind temporary constructed object to a lvalue in second case, hence an error

P0W
  • 46,614
  • 9
  • 72
  • 119
2

"myName" is a c-style string and it has the type of const char[]. Since it is not a std::string it needs to be converted to one. When that happens a temporary string is created. That temporary string cannot be bound to a reference but it can be bound to a const reference as it will extend its lifetime to the end of the expression.

You could also pass the string by rvalue reference like void foo(std::string && bar). This will move the temporary string into the function and give you the same effect.

A third option is to pass the string by value void foo(std::string bar). This works with temporaries and non temporaries and will wither make a copy or a move depending on the source of the string.

NathanOliver
  • 171,901
  • 28
  • 288
  • 402
0

The problem is with the & you are using for reference. When calling the function with a string literal you cannot pass a non-const reference.

Ahmed Akhtar
  • 1,444
  • 1
  • 16
  • 28