Home C++ Introduction Decisions Loops Input/Output Functions Stack and Heap References Arrays Searching and Sorting Recursion Pointers Character and Strings Structures Classes Inheritance Exceptions Templatess STL Modern C++ Misc Books ----

C++ 17 New Features


Contents

Template Class Deduction

We can deduce types for function templates. We can also deduce template types for classes with C++ 17.

File: class1.cpp
#include <iostream>
#include <thread>
#include <mutex>

using namespace std ;

mutex mtx ;

void thread_function1()
{
   for( int i1=0 ; i1<5 ; i1++ )
     {
        // Pre C++ 11
       //lock_guard<mutex> lk( mtx ) ;
       //With C++ 17
       lock_guard lk( mtx ) ;
       cout << "Thread function1: " << i1 << endl ;

     }

}



int main()
{
    thread t1( &thread_function1 );   // t1 starts running
    //cout << "main thread\n";

    // main thread waits for the thread t1 to finish
    t1.join();



    return 0;
}

Folding Expression

We had variadic templates that could handle a different number of arguments of different types. However the implementation was recursive. We have "folding expressions" in C++ 17 that gets rid of the recursive approach.

File: folding1.cpp
// C++ program to illustrate unary leftfold expression
#include <iostream>
using namespace std;

//Unary Left Fold:
//Syntax: (... op pack)
//Expansion: (((E1 op E2) op ...) op EN)
// sum_right(1, 2, 3) expands to ((1 + 2) + 3))

template <typename... Args> auto sum_left_fold_unary(Args... args)
{
    return (... + args);
}

//Unary Right Fold
// (  1 + ( 2 + 3 ) )
 template <typename... Args>
    auto sum_right_fold_unary(Args... args) {
        return (args + ...); // Unary Right Fold with addition
    }

// (((value + 3 ) + 1 ) + 2 )
//sum_left_fold_binary(  3, 1, 2 )
template <typename T,  typename... Args> auto sum_left_fold_binary(
    T initial_value ,  Args... args  )
{
    return (initial_value + ... + args);
}

// (((value + 3 ) + 1 ) + 2 )
//sum_left_fold_binary(  3, 1, 2 )
// ( value + (3 + (1 + 2)  ) )
template <typename T,  typename... Args> auto sum_right_fold_binary(
    T initial_value ,  Args... args  )
{
    return (initial_value + ... + args);
}

// Function template that accepts a variadic number of arguments
template<typename... Args>
void print_to_cout(Args&&... args)
{
    //binary operator
    // This expands to (cout << arg1 << arg2 << ... << argN)
    ( cout << ... << forward<Args>(args)  );

    cout << '\n'; // Add a newline at the end
}


int main()
{
    int sum1 = sum_left_fold_unary(  3, 1, 2 )  ;
    cout << "Result: " << sum1 << endl;

    int sum2 = sum_right_fold_unary(  3, 1, 2 )  ;
    cout << "Result: " << sum2 << endl;

    int sum3 = sum_left_fold_binary(  3, 1, 2 )  ;
    cout << "Result: " << sum3 << endl;

    int sum4 = sum_right_fold_binary(  3, 1, 2 )  ;
    cout << "Result: " << sum4 << endl;


    print_to_cout("Hello", " ", "World", "!")  ;
    print_to_cout(1, 2.5, 'c', "string_literal")  ;

    return 0;
}


File: folding2.cpp
#include <iostream>
#include <string>


using namespace std ;

template <typename T>
void Log(T object) {
    std::cout << object << ' ';
}

template <typename... Types>
void Fold(Types... args)
{
    // Unary right fold with the comma operator
    (Log(args), ...);
    // Expands to: Log(arg1), Log(arg2), Log(arg3), ...
}

int main()
{
    Fold("Hello", "World", 123, 4.5); // Output: Hello World 123 4.5

    return 0 ;
}