C++11 Tidbits: Non-static Data Member Initializers

Hi!

starting this month, thanks also to Chris (Jones) help and encouragement, I'm posting here the "C++11 tidbits" which I usually contribute to the Tools group Linux & VM partner newsletter. Enjoy! ;)

Despite the long name, Non-static Data Member Initializers are a rather straightforward new feature. In fact the GCC Bugzilla reveals novice C++ users often tried to use it in C++98, when the syntax was illegal! It must be said that the same feature is also available in Java, so adding it to C++ makes life easier for people using both languages.

The GCC implementation is brand new. It will be available soon in gcc-4.7.0 but it seems already quite stable and ready to play with.

People looking for self-contained specifications, outside the Standard itself, may consider fetching paper N2756 (and its earlier versions) from the ISO web site for more rationale.

In a nutshell, in C++11 the following are both legal:

  struct A
  {
    int m;
    A() : m(7) { }
  };

  struct B
  {
    int m = 7;   // non-static data member initializer
  };

thus the code:

  A a;
  B b;

  std::cout << a.m << '\n';
  std::cout << b.m << std::endl;

prints '7' followed by '7', because both the 'm' member of 'a' and the 'm' member of 'b' are initialized to 7.

A non-static data member initializer can be always overridden, thus:

  struct C
  {
    int m = 7;
    C() : m(14) { }
  };

  C c;

  std::cout << c.m << std::endl;

prints '14', not '7'.

This is actually very useful in practice, because it allows concisely written classes with many constructors, most relying on non-static initializers while default values are overridden for a few, selected data members. For interesting examples see the ISO papers.

In the examples we have been using built-in integer types, but the feature works with any kind of data member, for example std::string, std::vector, or any user-defined type. It also integrates nicely with other C++11 features like initializer lists. For example, the following is perfectly legal:

  struct D
  {
    std::vector<int> m{4, 5, 6};
  };

The code:

  D d;

  std::cout << d.m[0] << '\n';
  std::cout << d.m[1] << '\n';
  std::cout << d.m[2] << std::endl;

then prints '4', '5', and '6', on separate lines.

More non-trivial examples are available in the GCC test suite under g++.dg/cpp0x/nsdmi* and also in the C++ runtime library internals where the new construct is already exploited for the implementation of <mutex>. See, for example, once_flag, __mutex_base, and <condition_variable>.

As for all the other new C++ features, please don't hesitate to report bugs!

Comments:

Post a Comment:
  • HTML Syntax: NOT allowed
About

C++ enthusiasts only, please! ;)

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
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
   
       
Today