Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert char* to string&

Tags:

c++

I have the following code:

#include <iostream>
using namespace std;

int main(int argc, char *argv[])
{
    string &s1 = argv[0];           // error
    const string &s2 = argv[0];     // ok

    argv[0] = "abc";
    cout << argv[0] << endl;        // prints "abc"
    cout << s2 << endl;             // prints program name
}

I receive the following error for s1:

invalid initialization of reference of type 'std::string& {aka std::basic_string<char>&}' from expression of type 'char*'

Then why does the compiler accept s2?

Interestingly, when I assign a new value to argv[0] then s2 does not change. Does the compiler ignore that it's a reference and copies the value anyway? Why does it happen?

I write this in Code::Blocks 16.01 (mingw). The same happens with/without -std=c++11.

like image 513
Daniel Mernyei Avatar asked Dec 10 '22 14:12

Daniel Mernyei


2 Answers

Then why does the compiler accept s2?

Because a constant reference can bind to a temporary, and std::string has a constructor that can take a char * for a parameter.

That assignment constructs a so-called "temporary" object, and binds a constant reference to it.

Interestingly, when I assign a new value to argv[0] then s2 does not change.

Why should it change? s2 is a separate object. A std::string object does not maintain a pointer to a char * that created it. There are many ways to create a std::string. The actual string is owned by the object. If the std::string is constructed from a literal character string, it gets copied into the std::string. So, if the literal character string comes from a buffer, and the buffer is subsequently modified, it has no effect on the std::string.

like image 163
Sam Varshavchik Avatar answered Jan 08 '23 07:01

Sam Varshavchik


This line:

const string &s2 = argv[0]; 

Creates a new string instance, copying the contents of argv[0], and binds the reference to it. Later, this copy is outputted, which is now unrelated to the actual value of argv[0].

The temporary string objects lifetime, created in the quoted line, is expanded to the scope of the block, because a const reference was formed to it. See more at: Does a const reference prolong the life of a temporary?

like image 32
erenon Avatar answered Jan 08 '23 07:01

erenon