1

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?

10
  • 5
    There is no "practical or performance based reason". And, just to welcome you to C++, these days we will also write string example{"example"};. Commented Aug 11, 2022 at 11:21
  • 2
    One reason can be that it isn't the assignment operator that is used, It just looks like that (an inheritance from C). Therefore some people prefer to use = only for real assigment, and not for initialization. Commented Aug 11, 2022 at 11:22
  • 7
    auto example{"example"s}; Commented Aug 11, 2022 at 11:25
  • 4
    Because it reflects what happens. In both cases, your examples are actually calling a constructor which accepts a const char * to initialise example with the literal "example". In other words, your two examples - despite the syntactic differences - do EXACTLY the same thing. 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 the first is an assignment that calls std::strings operator=() function - which it doesn't. People who get tired of fielding such claims therefore sometimes prefer the second form. Commented Aug 11, 2022 at 11:41
  • 4
    "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." -- Most constructors will look like a method by the logic. You just have to be used to the syntax. Commented Aug 11, 2022 at 12:06

2 Answers 2

6

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"); 
Sign up to request clarification or add additional context in comments.

Comments

1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.