Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags more
Archives
Today
Total
관리 메뉴

Pure Software Engineer :)

[Item 7] Distinguising between () and {} when creating objects 본문

Software Engineering/Programming

[Item 7] Distinguising between () and {} when creating objects

HelloJaewon 2014. 12. 5. 19:48
int x(0);    // initializer is in parentheses  int y = 0;    // initializer follows "="  int z{0};    // initializer is in braces 

The use of an equals sign for initialization often misleads C++ newbies into thinking that an assignment is taking place, even though it's not.

Widget w1;    // call default constructor  Widget w2 = w1;    // not an assignment; calls copy ctor  Widget w1 = w2;    // an assignment; calls copy operator= 
class Widget { ...  private:     int x{0};    // fine, x's default value is 0     int y = 0;    // also fine     int z(0);    // error! };  std::atomic<int> ai1{0};    // fine std::atomic<int> ai2(0);    // fine std::atomic<int> ai3 = 0;    // error! 

Uniform initialization

C++11 introduces uniform initialization that can, at least in concept, be used anywhere and express everyting.
Of C++'s three ways to designate an initializing expression, only braces can be used every where.

class Widget { ...  private:     int x{0};    // fine, x's default value is 0     int y = 0;    // also fine     int z(0);    // error! };  std::atomic<int> ai1{0};    // fine std::atomic<int> ai2(0);    // fine std::atomic<int> ai3 = 0;    // error! 
#include <cstdio> #include <vector> #include <string>  class Widget { public:     Widget () {         printf("ctor 0\n");     }     Widget (int i, bool b) {         printf("ctor 1\n");     }     Widget (int i, double d) {         printf("ctor 2\n");     }     Widget(std::initializer_list<long double> il) {         printf("ctor 3\n");     } //    Widget(std::initializer_list<bool> il) { //        printf("ctor 4\n"); //    } //    Widget(std::initializer_list<std::string> il) { //        printf("ctor 5\n"); //    }     Widget(const Widget & rhs) {         printf("copy ctor\n");     }     Widget(const Widget && rhs) {         printf("move ctor\n");     }     operator float () const {         return 1.0f;     } };  int main () {     Widget w1(10, true);    // ctor 1     Widget w2{10, true};    // ctor 3     Widget w3(10, 5.0);     // ctor 2     Widget w4{10, 5.0};     // ctor 3     Widget w5(w4);          // copy ctor     Widget w6{w4};          // ctor 3     Widget w7(std::move(w4));   // move ctor     Widget w8{std::move(w4)};   // ctor 3     Widget w9;      // ctor 0     Widget w10{};   // ctor 0 //    Widget w11(); // vexing parse!     Widget w12({}); // ctor 3     Widget w13{{}}; // ctor 3      // use non-std::initializer_list ctor     // create 10-element std::vector     // all elements have value of 20     std::vector<int> v1(10, 20);     // use std::initializer_list ctor     // create 2-element std::vector     // element values are 10 and 20     std::vector<int> v2{10, 20};      return 0; } 

Things to Remember

Braced initialization is the most widely usable initialization syntax, it prevents narrowing conversions, and it's immune to C++'s most vexing parse.During constructor overload resolution, braced initializers are matched to std::initializer_list parameters if at all possible, even if other constructors offer seemingly better match.An example of where the choice between parentheses and braces can make a significant difference is creating a std::vector<numeric type> with two arguments.Choosing between parentheses and braces for object creation inside templates can be challenging. 

'Software Engineering > Programming' 카테고리의 다른 글

Facebook Folly Future  (0) 2015.07.19
[Item 8] Prefer nullptr to 0 and NULL  (0) 2014.12.07
Effective Modern C++  (0) 2014.12.05
[C++] 더블 디스패치 (double dispatch)  (0) 2014.10.25
[C++] bool vs. enum  (0) 2014.08.11