1
std::string str;
std::string(str);
std::string str = {};

Are they the same? If no then what's the difference? And when should I use each of them?

New to C++ and trying to understand the different ways of initializing std::string.

6
  • 1
    Recommended viewing: The Nightmare of Initialization in C++ Commented May 23, 2024 at 18:45
  • After viewing, read Initialization Definitely follow the links outlining the details of the various different types of initialization to get all of the syntax options down. Commented May 23, 2024 at 18:47
  • Actually, you might want to read the linked documentation page first. About 1/4 of the way down the page It uses std::string to demonstrate the many forms of initialization. Commented May 23, 2024 at 18:49
  • The three examples you quote are all the same. Initialzation in C++ is a horrible mess. Commented May 23, 2024 at 18:50
  • Hope we're not scaring you too badly, but "nightmare" and " horrible mess" are both apt descriptions. Commented May 23, 2024 at 18:55

1 Answer 1

2

These two declarations

std::string str;
std::string(str);

are equivalent. A declarator may be enclosed in parentheses.

Here is an example of an array declaration.

int ( ( ( a )[N1] )[N2] );

though the parentheses are redundant.

As for this declaration

std::string str = {};

then there is used the copy-initialization that requires that the default constructor would be acceptable. If it is declared as explicit (for the class std::string it is not explicit) then the compiler will issue an error.

Here is a demonstration program that produces a compiler error.

int main()
{
    struct A
    {
        explicit A() = default;
    };

    A a = {};
}

If in the demonstration program to change the declaration of the object a from

A a = {};

to

A a{};

then the program will compile because in that case there will not be the copy-initialization. There will be used the direct-initialization.

As for the original declarations then they all use the default constructor of the class std::string that is not declared as explicit. So all three declarations have the same effect.

Sign up to request clarification or add additional context in comments.

4 Comments

"then there is used the copy-initialization"... That's not quite right. It requires copy initialization to be available, but then skips it entirely and just directly constructs the object from {}
@MooingDuck From the C++ 17 Standard "15 The initialization that occurs in the = form of a brace-or-equal-initializer or condition (6.4), as well as in argument passing, function return, throwing an exception (15.1), handling an exception (15.3), and aggregate member initialization (8.5.1), is called copy-initialization."
Huh. Well, you're technically correct, but what I meant to refer to was the fact that it doesn't actually execute the copy-constructor. C++17 § 11.6 (17.6.1) — If the initializer expression is a prvalue and the cv-unqualified version of the source type is the same class as the class of the destination, the initializer expression is used to initialize the destination object. [Example: T x = T(T(T())); calls the T default constructor to initialize x. — end example ], and your answer is ambiguous about that.
Copy-initialization often doesn't execute the copy constructor. But it doesn't mean it will either. I think it's fair that it is italicized so that people know it's a term with an actual meaning and not loose language. I didn't see an implication that it would execute a copy constructor.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.