Template in C++ - from first tries toward generic programming to variadics

adib      11/22/2020

One of the first works done to be generic in programming was implementing the number of overloads that we want for that function template. Although in this way of doing generics, we couldn't reach complete templates.

Also overloading functions itself is very useful nowadays, but that time for the solving generic programming problems it came to the scene. Now take a look at getting generic by using overloads:

// function template for integers
int func(int a, int b)
{
	return a + b;
}

// function template for doubles
double func(double a, double b)
{
	return a + b;
}

// function template for strings
// if applicable, and just to be an example of templates
string func(string a, string b)
{
	return a + b;
}
    
int main()
{
    // here when we pass some integer to func(),
    // the integer version would be called
	func(1, 3);

	// double(float) version
	func(6.5, 4.2);

	// string version
	func("A", "B");
}

Simple function template

Also there are class templates, but they are much like function templates.
Normal template functions in C++:

// Basic function template
template <typename T>
T func(T a, T b)
{
    return a + b;
}

int main()
{
    // here when we pass some integer to func(),
    // T will be replaced with integer
    func(1, 3);

    // double(float) version
    func(6.5, 4.2);

    // string version
    func("A", "B");
}

Variadic Templates

As the name suggests, the name variadic is come from varying.

And the idea of variadic templates can come from problems like being stuck in situations like resource management issues or memory leak problems when you define overloads and you forget to free the memory for the program.

Variadic template also has made function overloading much easier. By having one template you can request the function overloads you want, and the template executes it in the right way for you. Here I explained how Variadic Template is defined:

// Base version
template <typename U>
void printspecs(const U& u)
{
    cout << "properties of the car entered : " << u << endl;
}


// A car show spec method
template <typename Model, typename... Props>
void printspecs(const Model& model, const Props&... prop)
{
    // car model
    cout << "properties of the car entered : " << model << endl;

    // other properties of that car
    printspecs(prop...);

}


int main()
{
    // Done, using string streams

    int year = 2019;
    string model = "750li";

    ostringstream oss;
    oss << model << year;
    cout << oss.str();


    // Done using variadic template
    printspecs(750, "New", 2019);

}

Change extension Pack Behaviour

Declaring how many args expansion pack is, is on your decision. you can force as many arguments as you want to execute the function in the best way

template <typename First, typename Second, typename... Rest>
    void calc(const First& first, const Second& second, const Rest&... rest)
    
template <typename One, typename Two, typename Three, typename... Rest>
    void calc(const One& one, const Two& two, const Three& three, const Rest&... rest)

Thanks for reading. Any Comments,

Please let me know at adibh1996@gmail.com