Wednesday, August 16, 2017

C++11: C99 Features: _Pragma

A functional form of pragma was added. _Pragma( X ) expands to #pragma X
This does not work on Microsoft Visual Studio 2015.  You need to replace _Pragma with __pragma


C++11: C99 Features: __func__

The macro __func__ was added, so that you could get the string of the current function. This is useful for trace statements.


C++11: Alignment

You can use the alignof() function to get the alignment (in number of bytes) of a type. Here is an example:
constexpr int intAlignmentInBytes = alignof(long long);


C++11: Alignment

You can specify the alignment of arrays with the alignas() operator. Previously, if you allocated bytes, you could not guarantee the alignment, which caused exceptions when the bytes were used as raw memory to back larger data types. Here is an example:
alignas(double) unsigned char buffer[1024];


C++11: Attributes

Attributes where added to C++11. They are contained within double square brackets: [[…]]. The double brackets can have spaces between them. The attributes come right after the entity they modify.  The attributes can be future C++ options, or vendor-specific options.


C++11: Raw String Literals

If you have a lot of characters that need to be escaped, you can use raw string literals to simplify a string. Here is an example:

#include <iostream>
int main()
{
  std::cout << R"(\\\\\)" << std::endl;
  return 0;
}
// Output: \\\\\
Reference: https://isocpp.org/wiki/faq/cpp11-language-misc#raw-strings

C++11: Static Assertion


static_assert(<bool_constexpr> , <message>); was added to c++11.
Here is an example:

static_assert( (sizeof(long) == 3), "Error: the type int is not 3 bytes");
int main() {return 0;}
// Output During Compile: error C2338: Error: the type int is not 3 bytes

Reference: https://isocpp.org/wiki/faq/cpp11-language-misc#static-assert
                  http://en.cppreference.com/w/cpp/language/static_assert

C++11: Local Types as Template Arguments

Local and Unnamed types can now be used as template arguments.


C++11: Variadic Templates

Variadic Parameters were added to Templates.

#include <iostream>

template<class ... Ts>
void f(Ts ... args)
{
  const int size = sizeof...(args) + 1;
  int res[size] = {1, args...};

  std::cout << "------" << std::endl;
  for (int i = 1; i < size; i++)
  {
    std::cout << res[i] << std::endl;
  }
}

int main()
{
  f();
  f(1);
  f(1, 2);
  f(1, 2, 3);
  return 0;
}
/* Output:
------
------
1
------
1
2
------
1
2
3
*******/

References: https://isocpp.org/wiki/faq/cpp11-language-templates#variadic-templates
                    http://en.cppreference.com/w/cpp/language/parameter_pack

C++11: Template Aliases

You can create Template that renames another template, but with some template parameters filled in. Here is an example:

template<class T, class U, class V>
struct MyTemplate {T t; U u; V v;};

template<class T>
using MyTemplateUV =  MyTemplate<T, int, float>;

MyTemplateUV<int>           s = {1, 2, 3.0};
MyTemplate  <int,int,float> t = {4, 5, 6.0};

int main()
{
  t = s;
  return 0;
}

Reference: https://isocpp.org/wiki/faq/cpp11-language-templates#template-alias

Monday, August 7, 2017

C++11: Suffix Return Type Syntax


The following function:
      int function();
Can also be written like:
      auto function() -> int;
Reference: https://isocpp.org/wiki/faq/cpp11-language-misc#suffix-return

C++11: Right-angle Brackets


list<vector<string>> lvs; works
Reference: https://isocpp.org/wiki/faq/cpp11-language-misc#right-angles

C++11: Preventing narrowing

{} initialization doesn’t narrow

C++11: The value of __cplusplus

The value of __cplusplus for C++11 is 20113L.

C++11: Extern templates

Templates can be declared as extern, so that they are redundantly specialized.

C++11: PODs (Plain Old Data)

POD data lets you interoperate with C. The binary layout are compatible. C++11 PODs do not matter on whether or not you have constructors.

C++11: Unions: Members with CTORs and DTORs

Unions can now allow members with CTORs and DTORs. They are marked deleted by the compiler.

C++11: long long

A long long type is an integer that is at least 64-bits long. A long type can be less than 64-bits.

C++11: enum class: Underlying Type

You can specify the underlying type of an enum class. Here is an example:

#include <iostream>
enum       EnumDefault                   {A, B};
enum       EnumChar          : char      {C, D};
enum       EnumShort         : short     {E, F};
enum       EnumInt           : int       {G, H};
enum       EnumLongLong      : long long {I, J};
 
enum class EnumClassDefault              {A, B};
enum class EnumClassChar     : char      {C, D};
enum class EnumClassShort    : short     {E, F};
enum class EnumClassInt      : int       {G, H};
enum class EnumClassLongLong : long long {I, J};
 
int main()
{
  std::cout << sizeof(EnumDefault      ) << " " <<
               sizeof(EnumChar         ) << " " <<
               sizeof(EnumShort        ) << " " <<
               sizeof(EnumInt          ) << " " <<
               sizeof(EnumLongLong     ) << " " <<
 
               sizeof(EnumClassDefault ) << " " <<
               sizeof(EnumClassChar    ) << " " <<
               sizeof(EnumClassShort   ) << " " <<
               sizeof(EnumClassInt     ) << " " <<
               sizeof(EnumClassLongLong) << std::endl;
  return 0;
}
// Output: 4 12 4 8 4 1 2 4 8
Reference: https://isocpp.org/wiki/faq/cpp11-language-types#enum-class

C++11: enum class

enum classes do not get implicitly converted to an integer. enum classes are scoped. Here is an example:

enum Alpha {A, B, C};
enum class Beta {X, Y, Z};
int main()
{
    Alpha alpha = A;
    Beta  beta  = Beta::X;
    int   alpha_int = alpha;
    int   beta_int  = static_cast(beta); // Cast is necessary in order to compile.
    return 0;
}
Reference: https://isocpp.org/wiki/faq/cpp11-language-types#enum-class

Monday, July 31, 2017

C++11: Explicit conversion operators

Conversion operators can now be marked as explicit.

C++11: Override Controls: final

You can declare a function to be final in a base class, which will prevent any derived class from overriding that function.

C++11: Override Controls: override

You can tell the compiler that you are attempting to override a function, so that the compiler can check whether you are really overriding the function or just overloading the function.

C++11: Inherited Constructors

You can pull Base Class Constructors into a Derived Class’ scope. Here is an example:
#include <iostream>
class Base
{
 public:
  Base(int i) {std::cout << "Base One Parameter CTOR called.  ";}
};
class Derived : public Base
{
  using Base::Base; // Without this line, the program would not compile.
};
int main()
{
  Base    base(1)   ;
  Derived derived(1);

  return 0;
}
// Output: Base One Parameter CTOR called.  Base One Parameter CTOR called.
Reference: https://isocpp.org/wiki/faq/cpp11-language-classes#delegating-ctor

C++11: In-class member initializers: non-static data members

Non-static data members can be initialized where they are declared in the class. Here is an example:
#include <iostream>
class A
{
 public:
  int a = 1;
};
int main()
{
  A a;
  std::cout << a.a << std::endl;
  return 0;
}
// Output: 1
References: http://en.cppreference.com/w/cpp/language/data_members
https://isocpp.org/wiki/faq/cpp11-language-classes#member-init

C++11: Delegating Constructors

You can now call a constructor from the MIL (Member Initialization List) of another constructor from the same class.
#include <iostream>
class A
{
 public:
  int m_a;
  A() : A(42) {}
  A(int a) : m_a(a) {}
};
int main()
{
  A a;
  std::cout << a.m_a <<  std::endl;
  return 0;
}
// Output: 42
Reference: https://isocpp.org/wiki/faq/cpp11-language-classes#delegating-ctor

C++11: =delete

Specifying =delete for any of the compiler-generated constructors or assignment operators, makes them unavailable. Here is an example:
#include <iostream>
class A
{
 public:
  A() {std::cout << "Default CTOR called; ";}
  A(const A& a) = delete;
};
int main()
{
  A a1;
  // A a2(a1); // This line does not compile because of " = delete' above.
  return 0;
}
// Output: Default CTOR called
Reference: https://isocpp.org/wiki/faq/cpp11-language-classes#default-delete

C++11: =default

Instead of providing a body for a class constructors or assignment operators, you can specify =default in the declaration. Here is an example:
#include <iostream>
class A
{
 public:
  A() = default; // Without this line, this file will not compile.
  A(const A& a)      {std::cout << "Copy CTOR called; ";}
  A& operator=(A& a)
  {
    std::cout << "Assignment Operator called; ";
    return *this;
  }
};
int main()
{
  A a1;
  A a2(a1); // Copy CTOR called
  a1 = a2;  // Assignment Operator called
  return 0;
}
// Output: Copy CTOR called; Assignment Operator called;

Reference: https://isocpp.org/wiki/faq/cpp11-language-classes#default-delete

C++11: User-defined Literals: Four Kinds

There are four kinds of user-defined literals: Integer, Floating Point, String, and Char. Here are examples of each one.
#include &ltiostream&gt
int          operator""_type1 (unsigned long long   i               )
  {return 1  ;} // Integer Literal
double       operator""_type2a(long double          d               )
  {return 2.1;} // Floating-point Literal (Cooked)
double       operator""_type2b(const char         * s               )
  {return 2.2;} // Floating-point Literal (Raw)
const char * operator""_type3 (const char         * s, size_t length)
  {return s  ;} // String Literal
char         operator""_type4 (char                 c               )
 {return c  ;} // Character Literal

int main()
{
  std::cout << 5_type1       << " " 
            << 5.0_type2a    << " "
            << 5.0_type2b    << " " 
            << "Hello"_type3 << " "
            << 'c'_type4     << std::endl;
  return 0;
}
// Output: 1 2.1 2.2 Hello c
Reference: https://isocpp.org/wiki/faq/cpp11-language#udls

C++11: User-defined Literals

A User-defined literal is a constant that has a suffix that a class can define an operator for to handle. Here is an example:
#include &ltcmath&gt
#include &ltiostream&gt
int operator ""_z(unsigned long long i) { return (int)std::pow(2, i); }
int main()
{
  std::cout << 5_z << std::endl;
  return 0;
}
// Output: 32
Reference: https://isocpp.org/wiki/faq/cpp11-language#udls

Monday, July 24, 2017

C++11: Inline namespace: transitivity

Inline namespace behavior is transitive. For example: if you had three nested namspaces and the two inner namespaces were declared inline, then all of the inner namespaces’ symbols can be seen in the outer namespace.

C++11: Inline namespace

You can declare a namespace inline. This causes it’s symbols to be accessed as if they were contained in the enclosing namespace. Here is an example:

#include <iostream>
#define BOTTOM_VERSION 1
namespace Top {
#if BOTTOM_VERSION == 1
  inline 
#endif
 namespace Bottom_V1
 {
   const int v = 1;
 }
#if BOTTOM_VERSION == 2
  inline 
#endif
 namespace Bottom_V2
 {
   const int v = 2;
 }
}
int main()
{
  std::cout << Top::v            << " " << 
               Top::Bottom_V1::v << " " << 
               Top::Bottom_V2::v << std::endl;
  return 0;
}
// Output: 1 1 2
// If BOTTOM_VERSION is #defined as 2, then the output is: 2 1 2
Reference: https://isocpp.org/wiki/faq/cpp11-language#inline-namespace

C++11: Exceptions: current_exception()

You can call current_exception() to get a pointer to the current exception. The function returns the pointer of the type exception_ptr.

C++11: nullptr

The nullptr value is not an int. It’s type is std::nullptr_t.

C++11: nullptr

The preferred way of setting a pointer to the null pointer is to use the literal nullptr.

C++11: constexpr: object initialization

Marking an object definition to be constexpr guarantees the initialization will be done at compile-time.
Marking an object definition to be const does not guarantee the initialization will be done at compile-time.

C++11: constexpr: function declaration

By marking things constexpr, you can use them in initialization that is performed at compile-time. Here is an example:
#include <iostream>
constexpr int orBits(int bit2, int bit1, int bit0)
{
  return int(4 * int(bit2) | int(2 * bit1)+int(bit0));
}
int orBits2(int bit2, int bit1, int bit0)
{
  return int(4 * int(bit2) | int(2 * bit1)+int(bit0));
}
int main()
{
  int x = 7;
  switch (x)
  {
   case orBits(1, 1, 1):
    std::cout << 7 << std::endl;
    break;
  }

  switch (x)
  {
// case orBits2(1, 1, 1): // Error: expression did not evaluate to a 
                          //          constant.
    std::cout << 7 << std::endl;
    break;
  }

  return 0;
}
// Output: 7
Reference: https://isocpp.org/wiki/faq/cpp11-language#cpp11-constexpr

C++11: noexcept: copy and move

It is recommended that copy and move operations are specified as noexcept.

C++11: noexcept: noexcept(true)

Specifying “noexcept” is equivalent to specifying “noexcept(true)”.

C++11: noexcept: destructors

A destructor should not throw any exceptions.  Compiler generated destructors are implicitly marked as noexcept.

Monday, July 17, 2017

C++11: noexcept

The ‘noexcept’ keyword is the preferred replacement for the ‘throw()’ exception specification.


C++11: Lambda Expressions: Function Objects

Lambda Expressions can be used in place of function objects. For example, as the comp parameter in the std:: sort() template function.
template
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

                      http://www.cplusplus.com/reference/algorithm/sort/

C++11: Lambda Expressions: Capture List

In a lambda expression, “[]” and it’s contents define the capture list.
The following are some variations of the capture list:
[] captures nothing
[&] captures all local variables by reference
[=] captures all local variables by value
[this] captures the current object by reference
[a] captures local variable a by copy
[&a] captures local variable a by reference
Here is an example:
#include
int main()
{
  int local1 = 3;
  int local2 = 4;
  [&](int param1, int param2) {std::cout << param1 << " " << param2 << " "
                                         << local1 << " " << local2 << std::endl;}(1, 2);
  return 0;
}
// Output: 1 2 3 4



C++11: Lambda Expressions: Parameter Passing

The example below shows how to pass parameters to a lambda expression.
#include
int main()
{
  [](int param1, int param2) {std::cout << param1 << " " << param2 << std::endl;}(1, 2);
  return 0;
}
// Output: 1 2



C++11: Lambda Expressions

Lambda Expressions let you define unnamed functions. Here is an example:
#include
int main()
{
  []() {std::cout << 1 << std::endl;}();
  return 0;
}
// Output: 1



C++11: Perfect Forwarding

This is the ability to wrap a function without creating all combinations constness overloads. Here is an example:

#include
template
void func(T i)
{
  std::cout << i << " ";;
}

template
void wrapper_without_perfect_forwarding(T& i)
{
  func(i);
}

template
void wrapper_with_perfect_forwarding(T&& i)
{
  func(std::forward(i));
}

int main()
{
  int variable = 1;
  wrapper_without_perfect_forwarding(variable);
  // wrapper_without_perfect_forwarding(2); // Error: 'void wrapper_without_perfect_forwarding(T &)':
                                                                                  //                   cannot convert argument 1 from 'int' to 'int &'
  wrapper_with_perfect_forwarding(variable);
  wrapper_with_perfect_forwarding(3);

  return 0;
}
// Output: 1 1 3


C++11: Universal Reference

A reference that binds to both lvalues and rvalues. An example of a Universal Reference is an Rvalue Reference to a template type parameter. Scott Meyer invented the term, by the C++ committee prefers the term ‘Forwarding Reference’.

C++11: Reference Collapsing

When the compiler changes ‘references to references’ into ‘references’ in certain situations.
Example:
Typedef A  B;
Typedef B  C;
C       var; // Var is type A
--
Typedef A& B;
Typedef B  C;
C       var; // Var is type A&
--
Typedef A  B;
Typedef B& C;
C       var; // Var is type A&
--
Typedef A&  B;
Typedef B&  C;
C       var; // Var is type A&
--
Typedef A&&  B;
Typedef B&&  C;
C       var;  // Var is type A&&
--
Reference collapsing can also happen with decltype specifiers and template type parameters. Reference Collapsing for References (&) existed pre-C++11.  Reference Collapsing for Rvalue References was added in C++11.

https://www.ibm.com/support/knowledgecenter/en/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/language_ref/reference_collapsing.html

C++11: Rvalue References: Move Constructors

There are two Move Contructors: MyClass(MyClass &&) and MyClass(const MyClass &&). Here is an example:

#include 
struct MyClass
{
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}

};

int main()
{
    MyClass          myNonConstObject; // Default CTOR called
    MyClass const    myConstObject;    // Default CTOR called
    MyClass       && myRefToNonConstObject(
                       []{MyClass nco; // Default CTOR called
                           return nco; 
                         }()); // Move CTOR called
    MyClass const && myRefToConstObject   (
                       []{MyClass const co; // Default CTOR called
                           return co;
                         }()); // Move CTOR2 called
    return 0;
}
 Output:
Default CTOR called
Default CTOR called
Default CTOR called
Move CTOR called
Default CTOR called
Move CTOR2 called
--
The following changes to the code and the result of the change.
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}

Compiles
Output:
Default CTOR called
Default CTOR called
Default CTOR called
Move CTOR2 called
Default CTOR called
Move CTOR2 called
--
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
Does not compile.
Error: attempting to reference a deleted function
--
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
Compiles.
Output:
Default CTOR called
Default CTOR called
Default CTOR called
Default CTOR called
--
  //MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
Does not compile.
Error: no appropriate default constructor available.
--
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Copy CTOR called"  << std::endl;}
  MyClass(const MyClass &) {std::cout << "Copy CTOR2 called" << std::endl;}
Compiles
Output:
Default CTOR called
Default CTOR called
Default CTOR called
Copy CTOR called
Default CTOR called
Copy CTOR2 called
--
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Copy CTOR called"  << std::endl;}
  MyClass(const MyClass &) {std::cout << "Copy CTOR2 called" << std::endl;}
Compiles
Ouput:
Default CTOR called
Default CTOR called
Default CTOR called
Copy CTOR2 called
Default CTOR called
Copy CTOR2 called
--
  MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
  MyClass(MyClass &&)       {std::cout << "Copy CTOR called"  << std::endl;}
  //MyClass(const MyClass &) {std::cout << "Copy CTOR2 called" << std::endl;}

Does not compile
Error: attempting to reference a deleted function
--
  //MyClass()                 {std::cout << "Default CTOR called"       << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Move CTOR called"  << std::endl;}
  //MyClass(const MyClass &&) {std::cout << "Move CTOR2 called" << std::endl;}
  //MyClass(MyClass &&)       {std::cout << "Copy CTOR called"  << std::endl;}
  //MyClass(const MyClass &) {std::cout << "Copy CTOR2 called" << std::endl;}
Compiles:
Output: None
Reference: https://isocpp.org/wiki/faq/cpp11-language#rval
http://en.cppreference.com/w/cpp/utility/move

C++11: Rvalue References


In C++98,
references-to-non-const can bind to lvalues
references-to-const can bind to lvalues
references-to-const can bind to rvalues
In C++11, the following was added:
rvalue_references-to-non-const can bind to rvalues
rvalue_references-to-const can bind to rvalues
Here is an example:
int main()
 {
int                                           lvalue                                                                     = 3;

int                           &             xxxxxx_ref_to_non_const_bound_to_lvalue                = lvalue;
int const                 &             xxxxxx_ref_to_xxx_const_bound_to_lvalue = lvalue;
//             int                           &             xxxxxx_ref_to_non_const_bound_to_rvalue = 3; // Compile Error
int const                 &             xxxxxx_ref_to_xxx_const_bound_to_rvalue = 3;

//             int                           &&          rvalue_ref_to_non_const_bound_to_lvalue = lvalue; // Compile Error
//             int const                 &&          rvalue_ref_to_xxx_const_bound_to_lvalue  = lvalue; // Compile Error

int                           &&          rvalue_ref_to_non_const_bound_to_rvalue                = 3;
int const                 &&          rvalue_ref_to_xxx_const_bound_to_rvalue = 3;

    return 0;
}


Monday, July 10, 2017

C++11: Rvalue References: Move

A move() template function tells the compiler to move from source instead of first copying from source. The source is changed to a "cheap default", i.e., an object that is inexpensive to create and delete. Here is an example:

#include
int main()
 {
    int   i  = 3;
    int & ri = i;
    int   j  = 4;
    int & rj = j;
    rj       = std::move(ri);
    std::cout << rj << std::endl;
    return 0;
}
// Output: 3
The move() template function is equivalent to a static_cast to an rvalue reference type.


C++11: Rvalue References

To eliminate a copy of a source object during construction or assignment, a destination can be defined as an rvalue, so that a move is made instead of a copy. The symbol for an rvalue reference is &&. Here is an example:
#include
int main()
 {
    int&& i = 3;
    std::cout << i << std::endl;
    return 0;
}
// Output: 3
The above problem doesn’t look too useful, but imagine that the ‘3’ was an invisible temporary, which is another form of an rvalue.


C++11: Uniform Initialization: Narrowing Conversions

{} initialization does not allow narrowing conversions. Here is an example:
int main()
 {
    unsigned int myUint  = { 1}; // Compiles
    unsigned int myUnit2 = {-1}; // Error: requires a narrowing conversion.
    return 0;
}


C++11: Initializer lists

You can get the size of an initializer list with the size() member function. Here is an example:
#include
#include
using namespace std;

int main()
 {
    initializer_list myInitializer_List;
    myInitializer_List = {10, 11, 12};
    cout << myInitializer_List.size() << endl;
    return 0;
}
// output: 3


C++11: Initializer lists

Initialializer lists must contain elements of the same type or convertible to the same type of the destination elements.


C++11: range-for: string

A string can be used with a range. Here is an example:
#include
#include
using namespace std;
int main()
 {
    string myString = "abc";
    for (auto i : myString)  cout << i << " ";
    return 0;
}
// Output: a b c

C++11: range-for: array

An array can be used with a range. Here is an example:
#include
#include
using namespace std;
int main()
 {
    int myArray[] = {10, 11, 12};
    for (auto i : myArray)  cout << i << " ";
    return 0;
}
// Output: 10 11 12


C++11: range-for: initializer list

An initializer list can be used with a range. Here is an example:
#include
#include
using namespace std;
int main()
 {
    for (auto i : {10, 11, 12}) cout << i << " ";
    return 0;
}
// Output: 10 11 12

C++11: range-for: standard containers

All standard containers can be used with a range.


C++11: decltype

decltype’s argument is either a name of a variable, a name of a type or an expression.


Friday, July 7, 2017

C++11: Initializer Lists

Initializer-lists can be any size.


C++11: Initializer Lists

Initializer-lists can be used in assignments.


C++11: Initializer Lists

You should prefer constructing objects with initializer lists over using pre-C++11 constructors that use ‘()’.


C++11: Initializer Lists

An initializer-list constructor is a constructor that has a single argument of type: std::initializer-list.


C++11: Initializer Lists

Initializer lists used to be limited to arrays.  Now that can be used with any type.

C++11: range-for

The following are examples of the ‘range-for’ statement:
for (auto element : vector) {}
for (auto& element : vector) {}
for (const auto element : vector) {}
for (const auto& element : vector) {}

The first returns copies of the vector elements in the loop, and the second returns references to the vector elements in the loop. The third and fourth examples are const versions of the first two.


C++11: range-for

The ‘range-for’ statement lets you iterate through a container that provides begin() and end() iterators.

C++11: decltype

decltype(N) can be used as a type specifier. The type used is the type of N. For example: int i; decltype(i) j; declares j to be of type int.


C++11: auto

‘auto ‘ can  be used for the type. The type will be inferred from the initializer. The old meaning of ‘auto’ as a storage specifier (stack variable) was made illegal.

C++03

C++03 replaced C++98. It consisted mostly of bug fixes. The most important bug fixed was the specification that Vector elements where stored contiguous in memory.  Most compilers already enforced this. This requirement allowed compatibility between C++ vectors and C arrays.