C++17 added the std::invoke() function,
which takes a callable object and parameters; and calls the callable object with
the parameters.
References:
#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:
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:
(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:
// 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:
#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:
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:
#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:
#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
#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:
#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:
#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:
#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
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
#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
#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:
#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:
#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:
#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:
#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:
#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:
#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:
[[nodiscard]]
int func()
{
return 0;
}
int main()
{
func();
return 0;
}
// Compiler Warning: warning C4834: discarding return value of function
with 'nodiscard' attribute
References:
Instead of:
namespace N1 { namespace N2 {
}}
You can write:
namespace N1::N2 {
}
Reference: https://en.wikipedia.org/wiki/C%2B%2B17
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:
#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
#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:
#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
#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
#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/
#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
#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
#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
#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
#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
#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