hehehehe
hehehehe

Reputation: 183

which one should i use and why: {} vs = in c++

I was watching MVA's(Microsoft Visual Academy's) tutorials and I came across these two operators i.e. {} and = to pass in the value to variables. I have done C programming so I am pretty much aware of the assignment operator =. But {} is not in any programming language I've worked on so far.

Kate is teaching the C++ course so she told that {} is used for copying.

But I was using the operator {} in the class below and it shows some error when I try to do this:

this->_width{new_width};

whereas below one works:

this->_width = new_width; 

Why so? I am also using {} to pass values in constructor but then they work perfectly. Only Problem is with member functions.

class Rectangle
{

public:
     void resize(int new_height, int new_width)  { this->_width{new_width} ; this->_height{new_height} };        //member function
     
     Rectangle(): _width{} , height{} {}   //constructor

private:
     int _width; 
     int _height; 

}; 

Upvotes: 8

Views: 21678

Answers (3)

Richard Hodges
Richard Hodges

Reputation: 69882

{} can be used to initialise variables in C++11 in the same way that they are used to initialise arrays and structures in C.

This has been introduced primarily to provide consistency in language syntax (initialising with {} will work in all contexts, whereas initialising using the assignment operator or () will work in specific contexts.

There is a further advantage to list initialisation in that it prevents narrowing - i.e. it prevents you from providing an integer when a double is required, or a short when an integer is required. In this way it can help to reduce bugs.

Note that {} cannot be used to pass values to a function - only to construct new objects.

This page is also worth reading

Upvotes: 18

Laura Maftei
Laura Maftei

Reputation: 1863

Non-static data members may be initialized in one of two ways:
1) In the member initializer list of the constructor.

struct S {
    int n;
    std::string s;
    S() : n(7) // direct-initializes n, default-initializes s
    { }
};

2) Through a brace-or-equal initializer, which is simply an initializer included in the member declaration, which is used if the member is omitted in the member initializer list

struct S {
    int n = 7;
    std::string s{'a', 'b', 'c'};
    S() // copy-initializes n, list-initializes s
    { }
};

You may use brace initializers in the member declaration.

Also, from the standard, N4296, § 9.2, paragraph 4:

A brace-or-equal-initializer shall appear only in the declaration of a data member.

Upvotes: 2

Damon
Damon

Reputation: 70136

Using {} is called uniform initialization in this context. It was introduced mainly for two reasons.

First, as the name indicates, initialization is uniform, that is it looks and works the same for single objects, arrays, containers that accept initializer lists, etc.

Second, and equally important, it is impossible to get a most vexing parse using curly braces, which is quite possible unintentionally otherwise:

A a(); // What does this do? What was probably intended?
B b{}; // And what does this do?

Also, as a bonus (kudos to @Richard Hodges), you avoid narrowing conversions using uniform initialization.

To literally answer the question "which one should I use?", you should preferrably use {} as it has only advantages, and no disadvantages (plus, Bjarne Stroustrup recommends using it).

Upvotes: 6

Related Questions