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.