(1) They both result in the same machine code, correct.
(1b)
With brackets you have to be careful, you can do:
Code:
std::string s{"Some string"}; // calls constructor just like s("Some string") would
It's also a general syntax to create objects, which the compiler can deduce:
Code:
std::string make_string()
{
return {"Hello"}; // returns object: std::string("Hello");
return {}; // returns empty std::string
}
It has the added property that it doesn't allow narrowing conversions:
Code:
double d = 5.0;
int n1(d); // fine
int n2{d}; // error, look at the message from your compiler
Edit: the entry form snipped away the rest of my post:
(2) Correct, str1 is a reference to const std::string, i.e. vows not to change the referenced object.
(3) Correct, a reference – once bound – cannot be unbound/rebound to something else, so a const specifier makes no sense but it would look like in your example.
It's worth mentioning that r-value references exist, which can bind to a temporary value (which prior only reference-to-const could) and even modify it over its lifetime:
Code:
std::string&& s = "Hello"; // r-value reference, notice the double &
s += " World!";
cout << s << endl; // Hello World!