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
#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

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
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