Home > OS >  Why would you declare a std::string using it's constructor?
Why would you declare a std::string using it's constructor?

Time:08-12

Most people when declaring strings in C , or most other languages, do it like so:

std::string example = "example";

However I've seen some code samples where it is done like this:

std::string example("example");

To me it seems like it needlessly obfuscates the code, particularly if there is a using std::string statement hiding somewhere above the declaration in the code making it look like

string example("example");

To some who may be new to the codebase or are coming from other languages it almost looks like it could be a method or a function.

Is there any practical or performance based reason for using the constructor instead of the assignment operator or does it come down to just personal preference?

CodePudding user response:

The practical reason for the second form is that it reflects what actually happens. Your two examples actually - despite their syntactic differences - do exactly the same thing.

They are both calling a constructor which accepts a const char * to initialise example with the literal "example".

The main difference is the way they are interpreted at times. I've lost count of the number of times I've seen people insist that

std::string example = "example";

does an assignment that calls std::strings operator=() function - except that it doesn't.

People who get tired of fielding such claims (and prefer that someone looking at the code can understand what it actually does, wherever possible) therefore sometimes prefer the second form;

std::string example("example");

CodePudding user response:

Sometimes you don't have a choice. Many constructors are explicit (even some of std::string's constructors) and you can't call it with the type object = value syntax, and for consistency type object(value) would be much better. Being explicit prevents mistakes on things like std::vector<char> v = 'c'; or MyString s = 'v'; that doesn't work as one expects

But C 11 introduced the new {} initializer syntax and most modern coding conventions strongly prefer it, so you should use this instead

std::string example{ "example" }; // good
auto example{ "example"s };       // better

Even ISO CPP's Core C Guidelines suggests that in ES.23: Prefer the {} initializer syntax

This has the advantage of preventing narrowing, and it works even for in-class initialization

struct foo {
    // OK
    std::string example1 = { "example" };
    std::string example2{ "example" };
    std::string example3 = "example";

    // Doesn't work
    std::string example4("example");
};

To some who may be new to the codebase or are coming from other languages it almost looks like it could be a method or a function.

That's the well-known most vexing parse issue in C . Both std::string example(std::string(someIdentifier)) and string example(string(someIdentifier)) can represent either a function declaration or a variable definition with initialization. If you learn C you have to learn the syntax

In fact most vexing parse is one of the reasons of the introduction to the new {} initialization form

See also

  • Related