Monday, October 30, 2017

C++17: std::invoke

C++17 added the std::invoke() function, which takes a callable object and parameters; and calls the callable object with the parameters.

References:


C++17: operator++(bool) was removed

C++17 removed the operator++(bool) function.


C++17: Logical operator traits

C++17 added the type traits: conjunction, disjunction, and negation.

References:


C++17: std::byte

C++17 added the std::byte type, which is neither a character nor a mathematical object.  It represents only a collection of bits.

References:


C++17: tagged union container

C++17 added a tagged union container. It is called std::variant. Here is an example:

#include <iostream>
#include <variant>

int main()
{
  std::variant<short, int, std::string> myVariant;

  myVariant = (short)1;

  std::cout << std::get<short>(myVariant) << " ";
  std::cout << std::get<0    >(myVariant) << " ";

  myVariant = 2;
  std::cout << std::get<int>(myVariant) << " ";
  std::cout << std::get<1  >(myVariant) << " ";

  myVariant = std::string("Three");
  std::cout << (std::get<std::string>(myVariant)).c_str() << " ";
  std::cout << (std::get<2          >(myVariant)).c_str() << " ";

  std::cout << std::endl;
  return 0;
}
// Output: 1 1 2 2 Three Three
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/utility/variant

C++17: Bessel functions

C++17 added the following Bessel functions:

regular modified cylindrical Bessel functions 
cyl_bessel_i
cyl_bessel_if
cyl_bessel_il

cylindrical Bessel functions (of the first kind)  
cyl_bessel_j
cyl_bessel_jf
cyl_bessel_jl
  
irregular modified cylindrical Bessel functions 
cyl_bessel_k
cyl_bessel_kf
cyl_bessel_kl
  
spherical Bessel functions (of the first kind) 
sph_bessel
sph_besself
sph_bessell
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/numeric/special_math

C++17: elliptic integrals

C++17 added the following elliptic integral functions:

(complete) elliptic integral of the first kind 
comp_ellint_1
comp_ellint_1f
comp_ellint_1l
 
(complete) elliptic integral of the second kind 
comp_ellint_2
comp_ellint_2f
comp_ellint_2l
  
(complete) elliptic integral of the third kind 
comp_ellint_3
comp_ellint_3f
comp_ellint_3l
  
(incomplete) elliptic integral of the first kind 
ellint_1
ellint_1f
ellint_1l
  
(incomplete) elliptic integral of the second kind 
ellint_2
ellint_2f
ellint_2l
  
(incomplete) elliptic integral of the third kind 
ellint_3
ellint_3f
ellint_3l
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/numeric/special_math
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1422.html

C++17: Parallel versions of STL algorithms

C++17 added parallel versions of some STL algorithms. Here is an example:

// The following program neither compiles on MSVS 2017 nor gcc version 6.3.0.
#include <algorithm>
//#include <execution>
#include <iostream>
#include <vector>

int main()
{
  std::vector<int> myVector{3, 1, 4, 5, 9, 2, 6};
//std::sort(std::execution::par, myVector.begin(), myVector.end());
  for (auto i : myVector)
  {
    std::cout << i << " ";
  }
  std::cout << std::endl;
  return 0;
}
// Theoretical Output: 1 2 3 4 5 6 9
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://www.bfilipek.com/2017/01/cpp17features.html#merged-the-parallelism-ts-aka-parallel-stl
http://en.cppreference.com/w/cpp/algorithm/execution_policy_tag_t
http://en.cppreference.com/w/cpp/algorithm/sort

C++17: New file system library

C++17 added a file system library. Here is an example:

#include <filesystem>
#include <iostream>

// "experimental" and "v1" are needed for MSVS 2017.
namespace fs = std::experimental::filesystem::v1;

int main()
{
  fs::path myPath (".\\cpp17filesystem.cpp");
  fs::path myPath2(".\\junk.txt"           );
  bool     fileWasRemoved                   = false;

  std::cout << fs::exists(myPath)  << " "; // 1
  std::cout << myPath.stem()       << " "; // cpp17filesystem
  std::cout << myPath.extension()  << " "; // .cpp
  fs::remove(myPath2);
  std::cout << fs::exists(myPath2) << " "; // 0
  fs::copy(myPath, myPath2);
  std::cout << fs::exists(myPath2) << " "; // 1
  fileWasRemoved = fs::remove(myPath2);
  std::cout << fileWasRemoved      << " "; // 1
  fileWasRemoved = fs::remove(myPath2);
  std::cout << fileWasRemoved      << " "; // 0
  std::cout << std::endl;
  return 0;
}
// Output: 1 cpp17filesystem .cpp 0 1 1 0
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/filesystem
http://www.bfilipek.com/2017/01/cpp17features.html#merged-file-system-ts
http://www.bfilipek.com/2017/08/cpp17-details-filesystem.html

C++17: Old Function Adapters Removed

C++17 removed the following binder and adaptor functions.

unary_function
binary_function
binder1st
binder2nd
bind1st
bind2nd
pointer_to_unary_function
pointer_to_binary_function
ptr_fun
mem_fun_t
mem_fun1_t
const_mem_fun_t
const_mem_fun1_t
mem_fun
mem_fun_ref_t
mem_fun1_ref_t
const_mem_fun_ref_t
const_mem_fun1_ref_t
mem_fun_ref
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/utility/functional

Monday, October 23, 2017

C++17: Removal of std::random_shuffle

C++17 removed the random_shuffle() template function.

References:

C++17: Removal of std::auto_ptr

C++17 removed the auto_ptr template class.


C++17: "contiguous iterators"

C++17 added a new type of iterator called a contiguous iterator. It is a refinement of the random access iterator. The added constraints are that the elements are contiguous in memory. An example of this is vector, which can be used to interface with C.

References:

C++17: Uniform container access

C++17 added the non-member functions empty(), size(), and data(). These functions provide uniform access to C++ Library Containers.

References:

C++17: insert_or_assign

C++17 added the insert_or_assign() function to the map and unordered_map containers. The function inserts an element or assigns an element if the key already exists. Here is an example:

#include <iostream>
#include <map>
#include <string>

int main()
{
  std::map<std::string, std::string> myMap;
  myMap.insert_or_assign("a", "apple"     );
  myMap.insert_or_assign("b", "bannana"   );
  myMap.insert_or_assign("c", "cherry"    );
  myMap.insert_or_assign("c", "clementine");

  for (const auto &pair : myMap)
  {
    std::cout << pair.first << " : " << pair.second << "; ";
  }
  std::cout << std::endl;
  return 0;
}
// Output: a : apple; b : bannana; c : clementine;
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/container/map/insert_or_assign

C++17: try_emplace

C++17 added the try_emplace() function to std:: map. The try_emplace() function stores a value if the key is not already there. Here is an example:

#include <iostream>
#include <map>
#include <string>

int main()
{
  std::map<std::string, std::string> myMap;
  myMap.try_emplace("a", "apple"     );
  myMap.try_emplace("b", "bannana"   );
  myMap.try_emplace("c", "cherry"    );
  myMap.try_emplace("c", "clementine");

  for (const auto &pair : myMap)
  {
    std::cout << pair.first << " : " << pair.second << "; ";
  }
  std::cout << std::endl;
  return 0;
}
// Output: a : apple; b : bannana; c : cherry;
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: std::uncaught_exceptions

C++17 deprecated std::uncaught_exception and added std::uncaught_exceptions (The ‘s’ was added).

References:

C++17: std::any

C++17 added an any class that can hold any object. Here is an example.

#include <any>
#include <iostream>
 
int main()
{
  int      myInt  ;
  std::any myAny  ;
 
  std::cout << myAny.has_value() << " ";
  try
  {
    myInt = std::any_cast<int>(myAny);
  }
  catch(std::bad_any_cast e)
  {
    std::cout << "bad ";
  }
  std::cout << ": ";
  myAny = std::any(3);
  std::cout << myAny.has_value() << " ";
  try
  {
    myInt = std::any_cast<int>(myAny);
  }
  catch(std::bad_any_cast e)
  {
    std::cout << "bad ";
  }
  std::cout << myInt << " ";
  std::cout << std::endl;
  return 0;
}
// Output: 0 bad : 1 3
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/utility/any

C++17: std::optional

C++17 added a template class that creates objects with optional values. Here is an example:

#include <iostream>
#include <optional>

int main()
{  
  std::optional<int> optionalInt;
  int                Int        ;

  Int = optionalInt.value_or(-1);
  std::cout << Int                     << " ";
  std::cout << optionalInt.has_value() << " ";
  try
  {
    Int = optionalInt.value();
  }
  catch(std::bad_optional_access e)
  {
    std::cout << "bad ";
  }
  std::cout << ": ";
  optionalInt = std::optional<int>(3);
  Int         = optionalInt.value_or(-1);
  std::cout << Int                     << " ";
  std::cout << optionalInt.has_value() << " ";
  try
  {
    Int = optionalInt.value();
  }
  catch(std::bad_optional_access e)
  {
    std::cout << "bad ";
  }
  std::cout << std::endl;
  return 0;
}
// Output: -1 0 bad : 3 1
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/utility/optional/value

C++17: std::string_view

C++17 added the class template string_view, which is a kind of lightweight constant string. Here is an example:

#include <iostream>
#include <string>
#include <string_view>

int main()
{
  std::string_view myStringView("A rat in the house.");
  std::string myString;

  myString = myStringView;
  
  std::cout << myString     << " ";
  std::cout << myStringView << " ";

  std::cout << std::endl;
  return 0;
}
// Output: A rat in the house. A rat in the house.
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/string/basic_string_view

Tuesday, October 17, 2017

C++17: Value of __cplusplus

C++17 changed the value of __cplusplus to 201703L



C++17: __has_include

C++17 added a macro that takes a header file name as an argument, and returns 1 if it was included already, and 0 if it was not. Here is an example:

#include <iostream>

#if __has_include(<iostream>) == 0
  #define INCLUDED_IOSTREAM_AGAIN true
  #include <iostream>
#else
  #define INCLUDED_IOSTREAM_AGAIN false
#endif

int main()
{
  if (INCLUDED_IOSTREAM_AGAIN)
  {
    std::cout << "Included  again." << std::endl;
  }
  else
  {
    std::cout << "Did not included  again." << std::endl;
  }
  return 0;
}
// Output: Did not included  again.
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: Inline variables

C++17 allows inline variables. Here is an example:

inline static int gMyInt;
inline static int gMyInt;

int main()
{
  return 0;
}
Note: the code neither compiles on “gcc version 6.3.0” nor “MSVS 15.3.5”
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: Template deduction of constructors

C++17 allows template deduction of constructors. Here is an example:

#include <iostream>

struct MyStruct
{
  template<typename T>
  MyStruct(T t)
  {
    std::cout << "T : ";
  }
};

template<>
MyStruct::MyStruct(int i)
{
  std::cout << "int : ";
}

template<>
MyStruct::MyStruct(double d)
{
  std::cout << "double : ";
}

int main()
{
  MyStruct myStructInt(1);
  MyStruct myStructDouble(2.2);
  MyStruct myStructString("Hello");
  std::cout << std::endl;

  return 0;
}
// Output: int : double : T :
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: Extensions on over-aligned memory allocation

C++17 allows memory alignment greater than std::max_align_t. Here is an example:

#include <iostream>

class A
{
};

class alignas(8) B
{
};

class alignas(256) C // Over-aligned
{
};

class alignas(1024) D // Over-aligned
{
};

int main()
{
  A a;
  B b;
  C c;
  C d;

  std::cout << sizeof(std::max_align_t) << " ";
  std::cout << &a << " ";
  std::cout << &b << " ";
  std::cout << &c << " ";
  std::cout << &d << " ";
  std::cout << std::endl;
  return 0;
}
// Output: 8 0050FCF7 0050FCE0 0050FB00 0050F900
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0035r4.html

C++17: Initializers in if and switch statements

C++17 allows an initializer in if and switch statements. Here is an example:

#include <iostream>

int main()
{
  if (int i = 4; int j = 0)
  {
    std::cout << "Branch1 ";
  }
  else
  {
    std::cout << "Branch2 ";
  }

  if (int i = 0; int j = 5)
  {
    std::cout << "Branch1 ";
  }
  else
  {
    std::cout << "Branch2 ";
  }

  std::cout << ": ";

  switch (int i = 4; int j = 0)
  {
   case 0:
    std::cout << "Branch1 ";
    break;
   case 4:
    std::cout << "Branch2 ";
    break;
  }

  switch (int i = 0; int j = 5)
  {
   case 0:
    std::cout << "Branch1 ";
    break;
   case 5:
    std::cout << "Branch2 ";
    break;
  }
  std::cout << std::endl;
  return 0;
}
// Output: Branch2 Branch1 : Branch1 Branch2
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://www.modernescpp.com/index.php/cpp17-core

C++17: Structured binding declarations

C++17 provides structured binding declarations, which let you declare multiple variables initialized from a tuple or a struct. Here is an example:

#include <iostream>

struct MyStruct
{
  int    mA;
  int    mB;
  double mC;
  MyStruct() : mA(1), mB(2), mC(3.3) {};
};

int main()
{
  MyStruct myStruct;

  auto [a, b, c] = myStruct;

  std::cout << a << " " << b << " " << c << std::endl;
  return 0;
}
// Output: 1 2 3.3
References:
https://en.wikipedia.org/wiki/C%2B%2B17
https://skebanga.github.io/structured-bindings/

C++17: A compile-time static if

C++17 added a compile-time static if. It’s purpose is to allow the compiler to eliminate branches of an if statement. Here is an example:

#include <iostream>

int main()
{
  if constexpr (0)
  {
    std::cout << "Section Compiled Out" << " ";
  }
  else
  {
    std::cout << "Section Compiled In" << " ";
  }

  std::cout << std::endl;
  return 0;
}
// Output: Section Compiled In
References:
https://en.wikipedia.org/wiki/C%2B%2B17
https://tech.io/playgrounds/2205/7-features-of-c17-that-will-simplify-your-code/constexpr-if

C++17: Fold expressions for variadic templates

C++17 added fold expressions for variadic templates. Here is an example:

#include <iostream>

template<typename... Args>
bool AllTrueRight(Args... args) { return (args && ...); }

template<typename... Args>
bool AllTrueLeft(Args... args) { return (... && args); }

template<typename... Args>
int SumUnaryRight(Args... args) { return (args + ...); }

template<typename... Args>
int SumUnaryLeft(Args... args) { return (... + args); }

template<typename... Args>
int SubBinaryRight(Args... args) { return (args - ... - 100); }

template<typename... Args>
int SubBinaryLeft(Args... args) { return (100 - ... - args); }

int main()
{
  bool bResult = false;
  int  iResult = -1;

  bResult = AllTrueRight(true, true, true, false);
  std::cout << bResult << " "  ;

  bResult = AllTrueRight(true, true, true, true);
  std::cout << bResult << " "  ;

  bResult = AllTrueLeft(true, true, true, false);
  std::cout << bResult << " "  ;

  bResult = AllTrueLeft(true, true, true, true);
  std::cout << bResult << " "  ;

  iResult = SumUnaryLeft(1, 2, 3, 4);
  std::cout << iResult << " "  ;

  iResult = SumUnaryRight(1, 2, 3, 4);
  std::cout << iResult << " "  ;

  iResult = SubBinaryRight(10, 9, 8); // (10-(9-(8-100))) = 10-(9+92) = 10 - 101 = -91
  std::cout << iResult << " "  ;

  iResult = SubBinaryLeft(10, 9, 8); // (((100-10)-9)-8) = (90-9)-8 = 81-8 = 73
  std::cout << iResult << " "  ;

  std::cout << std::endl;
  return 0;
}
// Output: 0 1 0 1 10 10 -91 73
Notes:
1) Needed to use: gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)
2) Commandline: g++ -std=c++17 *.cpp
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://en.cppreference.com/w/cpp/language/fold

C++17: Constant evaluation for all non-type template arguments

C++17 provides constant evaluation for all non-type template arguments. Here is an example:

#include <iostream>

template<int * p>
struct ST1
{
  int *mP = p; // C++98: Error; C++14: Good
};

template<int * i> 
struct ST2
{
  int mI = *i; // C++98: Error; C++14: Good
};

template<int (*pf)()>
struct ST3
{
  int mI = pf(); // C++98: Error; C++14: Good
};

struct S
{
  static int m;
};

int S::m = 42;
int gI   = 55;

///////////////////////////////////////////////////////////////////////////////
int myFunc()
{
  return 211;
}

///////////////////////////////////////////////////////////////////////////////
int main()
{
  S           s   ;
  ST1<&s.m  > st11; // C++14: Error, c++17: Good
  ST1<&S::m > st12;
  ST2<&gI   > st21;
  ST3<myFunc> st31;

  std::cout <<  s.m     << " ";
  std::cout << *st11.mP << " ";
  std::cout << *st12.mP << " ";
  std::cout <<  st21.mI << " ";
  std::cout <<  st31.mI << " ";

  std::cout << std::endl;
  return 0;
}
// Output: 42 42 42 55 211
References:
https://en.wikipedia.org/wiki/C%2B%2B17
https://stackoverflow.com/questions/33301552/non-type-reference-parameter-argument
https://isocpp.org/files/papers/n4268.html

Tuesday, October 10, 2017

C++17: [[maybe_unused]] Attribute

C++17 the [[maybe_unused]] attribute to handle a case where a variable is only sometimes used during a compile. An example of this is a variable that is only used in an assert() statement. When compiled in debug mode, this variable would be used; but when compiled in release mode, this variable would not be used.  This attribute disables the unused variable warning for variables specified with this attribute.

References:

C++17: Hexadecimal Floating-Point Literals

C++17 added hexadecimail floating-point literals. They are of the form 0x<hex_wholenumber>.<hex_fraction>p<power_of_2>. Here is an example:

#include <iostream>

int main()
{
  std::cout << 0x0p0     << " "; // ( 0.0/16.0 + 0.0/16     )*(2.0 ** 0.0)
  std::cout << 0x0.p0    << " "; // ( 0.0/16.0 + 0.0/16     )*(2.0 ** 0.0)
  std::cout << 0x.1p0    << " "; // ( 0.0/16.0 + 1.0/16     )*(2.0 ** 0.0)
  std::cout << 0x0.1p0   << " "; // ( 0.0/16.0 + 1.0/16     )*(2.0 ** 0.0)
  std::cout << 0x1.1p0   << " "; // ( 1.0/16.0 + 1.0/16     )*(2.0 ** 0.0)
  std::cout << 0x1.2p0   << " "; // ( 1.0/16.0 + 2.0/16     )*(2.0 ** 0.0)
  std::cout << 0x2.2p0   << " "; // ( 2.0/16.0 + 2.0/16     )*(2.0 ** 0.0)
  std::cout << 0x2.2p1   << " "; // ( 2.0/16.0 + 2.0/16     )*(2.0 ** 1.0)
  std::cout << 0x2.2p2   << " "; // ( 2.0/16.0 + 2.0/16     )*(2.0 ** 2.0)
  std::cout << 0x10.01p0 << " "; // (16.0/16.0 + 1.0/(16*16))*(2.0 ** 0.0)
  std::cout << 0x0.001p0 << " "; // (16.0/16.0 + 1.0/(16**3))*(2.0 ** 0.0)

  std::cout << std::endl;
  return 0;
}
// Output: 0 0 0.0625 0.0625 1.0625 1.125 2.125 4.25 8.5 16.0039 0.000244141
References:

C++17: Utf-8 Character Literals

C++17 added Utf-8 literals. They are specified with a u8 prefix.  Here is an example: auto c = u8’a’;


C++17: [[nodiscard]] Attribute

C++17 added the [[nodiscard]] attribute to specify that any function call that returns a value, has that value stored in the calling code, or else a warning is given: Here is an example:

[[nodiscard]]
int func()
{
  return 0;
}

int main()
{
  func();
  return 0;
}
// Compiler Warning: warning C4834: discarding return value of function
                                                with 'nodiscard' attribute
References:
https://en.wikipedia.org/wiki/C%2B%2B17
https://infektor.net/posts/2017-01-19-using-cpp17-attributes-today.html

C++17: [[fallthrough]] Attribute

C++17 added the [[fallthrough]] attribute to help protect against forgetting a break statement in a case statement. If a break is missing and the [[fallthrough]] attribute is not given then a warning may be given by the compiler.  MSVS 2017 does not handle this attribute.

References:

C++17: Shortened Nested Namespace Definitions

C++17 allows nested namespace definitions to be shortened.

Instead of:

namespace N1 { namespace N2 {
}}

You can write:

namespace N1::N2 {
}
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: New Rules for auto Deduction

Auto deduction for direct-list initialization must have only a single element. Here is an example:

int main()
{
  //auto v = {9, 10}; //Should be good, but error in MSVS 2017:
                      //  Copy-list-initialization. decltype(y) is
                      //  std::initializer_list.
  //auto w = {1, 2.0};//Error: Copy-list-initialization and types of 
                      //  elements of braced-init-list are not identical.
    auto x{3};        //Good: Direct list-initilization and single element.
                      //  decltype(x) is int.
  //auto y     = {3}; //Should be good, but error in MSVS 2017:
                      //  Copy-list-initialization. decltype(y) is
                      //  std::initializer_list.
  //auto z{3, 4};     //Error: Direct list-initialization and multiple
                      //  elements.
  return 0;
}
References:
https://en.wikipedia.org/wiki/C%2B%2B17
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html

C++17: Template template parameter can be declared typename

Before C++17 , a template template parameter had to be declared class. Here is an example:

#include <complex>
#include <iostream>

//                +----- Template Parameter
//                |
//                V                          
template<typename T>
class A
{
 public:
  T mT = T();
}; 
//                                  +----- Template Template Parameter
//                                  |
//                                  V                          
template<  template<typename> class U  >
class B
{
 public:
  U<int> mU;
};
//                                  +----- Template Template Parameter
//                                  |
//                                  V                          
template<  template<typename> class U  >
class C
{
 public:
  U<std::complex<double>> mU;
};

int main()
{
  B<A> b;

  std::cout << b.mU.mT << " ";

  C<A> c;

  std::cout << c.mU.mT << std::endl;

  return 0;
}
// Output: 0 (0,0)
Reference: https://en.wikipedia.org/wiki/C%2B%2B17

C++17: Trigraphs Removed

C++17 removed trigraphs. Trigraphs are three-character sequences representing one character. They were a workaround for some keyboards not having cetain characters. Here is an example of trigraphs in C++98.

#include <iostream>

int main()
{
  std::cout << "??="  << " "; // #
  std::cout << "??//" << " "; // /
  std::cout << "??'"  << " "; // ^
  std::cout << "??)"  << " "; // ]
  std::cout << "??("  << " "; // [
  std::cout << "??!"  << " "; // |
  std::cout << "??<"  << " "; // {
  std::cout << "??>"  << " "; // }
  std::cout << "??-"  << " "; // ~

  std::cout << std::endl;
}
// Output: # / ^ ] [ | { } ~
References:
https://en.wikipedia.org/wiki/C%2B%2B17
https://stackoverflow.com/questions/1234582/purpose-of-trigraph-sequences-in-c

C++17: Static_assert Message Optional

C++17 makes the text message for static_assert optional.


Tuesday, October 3, 2017

C++14: The std::quoted

C++14 allows you to quote strings. Here is an example:

#include <iomanip>
#include <iostream>

int main()
{
  std::cout << std::quoted("To quote: \"Hello.\"  ");
  std::cout <<             "To quote: \"Hello.\"  ";
  std::cout << std::endl;
  return 0;
}
// Output: "To quote: \"Hello.\"  "To quote: "Hello."
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Smaller_library_features

C++14: std::cbegin/std::cend/std::crbegin/std::crend

C++14 added functions that return constant iterators.


C++14: std::integer_sequence

C++14 added integer_sequence template class

#include <iostream>
#include <vector>
#include <utility>

void myPrintFunction(int a, int b, int c, int d)
{
std::cout << a << " " << b << " " << c << " " << d << std::endl;
}

template<typename T, T... Sequence>
void myTemplateFunction(std::integer_sequence<T, Sequence...>)
{
  myPrintFunction(Sequence...);
}

int main()
{
  std::integer_sequence<int, 2, 4, 6, 8> mySequence;
 
  myTemplateFunction(mySequence);

  return 0;
}
// Output: 2 4 6 8
Reference: https://cpprefjp.github.io/reference/utility/integer_sequence.html

C++14: std::integral_constant gained an operator()

C++14 added the member function operator() to integral_constant. Integral_constant wraps a static constant. operator() returns the constants value. Here is an example:

#include <iostream>
#include <type_traits>
using namespace std;

integral_constant<long long, 42ll> Answer;

int main()
{
  cout << Answer()     << " ";
  cout << Answer.value << " ";
  cout <<        integral_constant<long long, 42ll>::value_type(Answer) << " ";
  cout <<        integral_constant<long long,  0ll>::value_type(Answer) << " ";
  cout << sizeof(integral_constant<long long, 42ll>::value_type)        << " ";
  cout << sizeof(integral_constant<long long, 42ll>::type      )        << " ";

  cout << endl;
  return 0;
}
// Output: 42 42 42 42 8 1
Reference: http://www.cplusplus.com/reference/type_traits/integral_constant/

C++14: std::make_unique

C++14 added the make_unique template function to construct an object and wrap a unique_ptr around it. Here is an example:

#include <memory>

int main()
{
  std::unique_ptr<int  > myInt      = std::make_unique<int  >(42);
  std::unique_ptr<int[]> myIntArray = std::make_unique<int[]>(42);
  
  return 0;
}
Reference: http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique

C++14: Tuple addressing via type

C++14 added addressing a tuple component by type. Here is an example:

#include <iostream>
#include <string>
#include <tuple>

int main()
{
  std::tuple
                                        myTuple(1, 2, 3, 4.4f, 5.5, "six");

  std::cout << std::get<int        >(myTuple) << " ";
  std::cout << std::get<long       >(myTuple) << " ";
  std::cout << std::get<short      >(myTuple) << " ";
  std::cout << std::get<float      >(myTuple) << " ";
  std::cout << std::get<double     >(myTuple) << " ";
  std::cout << std::get<std::string>(myTuple) << " ";

  std::cout << std::endl;

  return 0;
}
// Output: 1 2 3 4.4 5.5 six
Reference: http://developeradventure.blogspot.com/2013/12/c14-tuple-addressing-via-type.html

C++14: Standard user-defined literals

C++14 defined several standard user-defined literals:
operator""if          imaginary float      std::literals::complex_literals
operator""I           imaginary double  std::literals::complex_literals
operator""il          imaginary long      std::literals::complex_literals
operator""h          hours                      std::literals::chrono_literals
operator""min      minutes                  std::chrono::duration
operator""s          seconds                   std::chrono::duration
operator""ms       milliseconds           std::chrono::duration
operator""us        microseconds         std::chrono::duration
operator""ns        nanoseconds          std::chrono::duration
operator""s          string                      std::literals::string_literals


Here is an example:

#include <chrono>
#include <complex>
#include <iostream>

int main()
{
  using namespace std::complex_literals;
  std::cout << 1.1if << " ";
  std::cout << 2.2i  << " ";
  std::cout << 3il   << " ";

  using namespace std::chrono_literals;
  std::cout << std::chrono::seconds    (4h  ).count() << " ";
  std::cout << std::chrono::seconds    (5min).count() << " ";
  std::cout << std::chrono::seconds    (6s  ).count() << " ";
  std::cout << std::chrono::nanoseconds(7ms ).count() << " ";
  std::cout << std::chrono::nanoseconds(8us ).count() << " ";
  std::cout << std::chrono::nanoseconds(9ns ).count() << " ";

  using namespace std::string_literals;
  std::cout << "Hello"s << " ";

  std::cout << std::endl;
  return 0;
}
// Output: (0,1.1) (0,2.2) (0,3) 14400 300 6 7000000 8000 9 Hello
Reference: http://en.cppreference.com/w/cpp/language/user_literal

C++14: Heterogeneous lookup in associative containers

C++14 added heterogeneous lookup in associative containers. It is enabled by specifying ‘less<>’ in the container template. Here is an example:

#include <iostream>
#include <functional>
#include <set>
using namespace std;

class MyClass0
{
  int mId;
 public:
  MyClass0(int id) : mId(id) {cout << "CTOR0 ";}
  bool operator< (const MyClass0 & rhs) const
  {
    return this->mId < rhs.mId;
  }
};

class MyClass1
{
  int mId;
 public:
  MyClass1(int id) : mId(id) {cout << "CTOR1 ";}
  bool operator< (const MyClass1 & rhs) const
  {
    return this->mId < rhs.mId;
  }
};

class MyClass2
{
  int mId;
 public:
  MyClass2(int id) : mId(id) {cout << "CTOR2 ";}
  bool operator< (const MyClass2 & rhs) const
  {
    return this->mId < rhs.mId;
  }
};

int main()
{
  set<MyClass0                 > mySet0;
  set<MyClass1, less<        > > mySet1; // Allows Heterogeneous Lookup.
  set<MyClass2, less<MyClass2> > mySet2;

  set<MyClass0                 >::iterator mySet0_iter;
  set<MyClass1, less<        > >::iterator mySet1_iter;
  set<MyClass2, less<MyClass2> >::iterator mySet2_iter;

  MyClass0 myObject0_1(1);
  mySet0.insert(myObject0_1);
  mySet0_iter=mySet0.find(myObject0_1);cout<<(mySet0_iter!=mySet0.end())<<" ";
  mySet0_iter=mySet0.find(MyClass0(1));cout<<(mySet0_iter!=mySet0.end())<<" ";
  mySet0_iter=mySet0.find(1          );cout<<(mySet0_iter!=mySet0.end())<<" ";
  cout << endl;

  MyClass1 myObject1_1(1);
  mySet1.insert(myObject1_1);
  mySet1_iter=mySet1.find(myObject1_1);cout<<(mySet1_iter!=mySet1.end())<<" ";
  mySet1_iter=mySet1.find(MyClass1(1));cout<<(mySet1_iter!=mySet1.end())<<" ";
  // The following does not compile in MSVS2014.
  //mySet1_iter=mySet1.find(1          );cout<<(mySet1_iter!=mySet1.end())<<" ";
  cout << endl;

  MyClass2 myObject2_1(1);
  mySet2.insert(myObject2_1);
  mySet2_iter=mySet2.find(myObject2_1);cout<<(mySet2_iter!=mySet2.end())<<" ";
  mySet2_iter=mySet2.find(MyClass2(1));cout<<(mySet2_iter!=mySet2.end())<<" ";
  mySet2_iter=mySet2.find(1          );cout<<(mySet2_iter!=mySet2.end())<<" ";

  cout << endl;
  return 0;
}
// Output(MSVS): CTOR0 1 CTOR0 1 CTOR0 1
//               CTOR1 1 CTOR1 1
//               CTOR2 1 CTOR2 1 CTOR2 1
//
// Output(g++):  CTOR0 1 CTOR0 1 CTOR0 1
//               CTOR1 1 CTOR1 1 CTOR1 1
//               CTOR2 1 CTOR2 1 CTOR2 1
Reference: https://en.wikipedia.org/wiki/C%2B%2B14#Heterogeneous_lookup_in_associative_containers

C++14: Shared Lock Type

C++14 added a Shared Lock Type. Here is an example:

#include <iostream>
#include <mutex>
#include <shared_mutex>

int main()
{
  std::shared_timed_mutex MySharedTimedMutex;

  std::shared_lock<std::shared_timed_mutex>
                                    MySharedLock(MySharedTimedMutex);
  if (MySharedLock.owns_lock())
  {
    std::cout << "R+ ";
  }
  else
  {
    std::cout << "R- ";
  }

  std::shared_lock<std::shared_timed_mutex>
                                   MySharedLock2(MySharedTimedMutex);

  if (MySharedLock2.owns_lock())
  {
    std::cout << "R+ ";
  }
  else
  {
    std::cout << "R- ";
  }

  MySharedLock.unlock();
  MySharedLock2.unlock();

  std::unique_lock<std::shared_timed_mutex>
                                    MyUniqueLock(MySharedTimedMutex);
  if (MyUniqueLock.owns_lock())
  {
    std::cout << "W+ ";
  }
  else
  {
    std::cout << "W- ";
  }
  return 0;
}
// Output: R+ R+ W+
Reference: http://en.cppreference.com/w/cpp/thread/shared_lock/shared_lock

C++14: Shared Timed Mutex

C++14 added a shared timed mutex. You can lock something as shared (like a reader lock) or exclusive (like a writer lock). Here is an example:

#include <iostream>
#include <shared_mutex>

int main()
{
  std::shared_timed_mutex MySharedTimedMutex;

  if (MySharedTimedMutex.try_lock_shared())
  {
    std::cout << "R+ ";
  }
  else
  {
    std::cout << "R- ";
  }
  if (MySharedTimedMutex.try_lock_shared())
  {
    std::cout << "R+ ";
  }
  else
  {
    std::cout << "R- ";
  }
  if (MySharedTimedMutex.try_lock())
  {
    std::cout << "W+ ";
  }
  else
  {
    std::cout << "W- ";
  }
  MySharedTimedMutex.unlock_shared();
  MySharedTimedMutex.unlock_shared();
  if (MySharedTimedMutex.try_lock())
  {
    std::cout << "W+ ";
  }
  else
  {
    std::cout << "W- ";
  }
  return 0;
}
// Output: R+ R+ W- W+
Reference: http://en.cppreference.com/w/cpp/thread/shared_timed_mutex