Pibben
Pibben

Reputation: 2025

What happens when you initialize a const reference by conversion constructor?

What happens when you initialize a const reference by conversion constructor? Is it any different from an ordinary assignment? Look at this code:

void func(const char* cstr) {
    std::string S1 = cstr;
    const std::string& S2 = cstr;
}

Is there any practical difference between S1 and S2? Why would you want to use the second expression?

Upvotes: 0

Views: 92

Answers (3)

Jarod42
Jarod42

Reputation: 217135

  • With std::string S1 = cstr;

    S1 is move-constructed from a temporary. That move-construct should probably be elided, but should be accessible. As not const, S1 can be modified.

  • With const std::string& S2 = cstr;

    S2 is a const reference to a temporary string, with extended lifetime. As const, S2 cannot be modified.

For type without move/copy constructor as

struct S {
    S() = default;
    S(const S&) = delete;
    S& operator =(const S&) = delete;
};

You may use the second form, but not the first one:

 S s1 = S{}; // Invalid
 const S& s2 = S{}; // Valid
 S&& s3 = S{}; // Valid too.

Upvotes: 1

BiagioF
BiagioF

Reputation: 9705

Is there any practical difference between S1 and S2?

In terms of performance, the answer is no. Both instructions invoke converting constructor and allocate memory, then copy the the char array in the internal dynamic memory of std::string instance.

In term of syntax, the answer is obviously the const-ness: in the successive block of the function the object handled by S2 cannot be modified.

Upvotes: 1

vz0
vz0

Reputation: 32923

You get a const reference to the S1 string, and the compiler enforces the const of the value. If you try to modify S2 it will not compile. For local variables it doesn't make much sense, except when you don't trust yourself to not modify S2, or when you are doing code refactorings moving things around and you want to be sure that S2 is never changed.

But if you pass a string as an argument to a function you can use a const reference to avoid a costly copy:

void f(const std::string& S2) { ... }

const in general won't help the compiler to perform optimizations to the code since you can always use const_cast to remove the const of a variable.

Upvotes: 0

Related Questions