• No results found

Parametric Polymorphism

N/A
N/A
Protected

Academic year: 2022

Share "Parametric Polymorphism"

Copied!
26
0
0

Loading.... (view fulltext now)

Full text

(1)

C++ Templates

(2)

Parametric Polymorphism

void printData(int value){

cout << "The value is “ << value << endl;

}

void printData(double value){

cout << "The value is “ << value << endl;

}

void printData(string value){

cout << "The value is “ << value << endl;

}

template<typename T>

void printData(T value){

cout << "The value is “ << value

<< endl;

}

double d=4.75;

string s("hello");

bool b=false;

printData(3); //T is int printData(d); //T is double printData(s); //T is string printData(b); // T is bool

(3)

Function Template

template <typename T>

T GetMax (T a, T b) {

T result = (a>b)? a : b;

return result;

}

void main(){

int i=5, j=6, k;

double d=3.14, e=5.0, f;

k=GetMax<int>(i,j);

f=GetMax<double>(d,e);

f=GetMax<double>(i,e);

}

Definition

Usage

(4)

Specifying Actual Template Arguments

• Explicit:

• Implicit:

template<typename T>

void func(){}

int main(){

func<int>();

func<double>();

}

template<typename T>

void func(T value) {}

template<typename T,typename U>

T func2(U value) { return T(value);

}

int main(){

// T=int

func(3);

// T=int, U=double

func2<int>(3.5);

}

The compiler can only deduce template arguments of function templates

(5)

Class Template

template <typename T>

class MyQueue {

std::vector<T> data;

public:

void add(T const &d);

void remove();

void print();

};

void main(){

MyQueue<int> q;

q.add(1);

q.print();

q.remove();

q.print();

template <typename T>

void MyQueue<T>::add(T const &d){

data.push_back(d);

}

Declaration

Definition

Usage

(6)

Template Parameters

• Type parameters

• typename X or class X

• X can be used anywhere a type can be used

• Non-Type parameters

– compile-time constants

• int, bool, address of a global variable

• No floating point values or string literals

• Template parameters

– Next slide…

template<int i>

class A{};

A<3> a3;

A<sizeof(string)> as;

(7)

Template as a Template Parameter

• Enable a template to be parameterized by the name of another template.

• Example: a class that lets you choose a container type

– A container is also a template

template<template<typename T> class ContainerType>

class MyClass{

ContainerType<int> intContainer;

ContainerType<string> stringContainer;

};

MyClass<vector>;

MyClass<list>;

(8)

Default Template Parameters

• Just like functions

– If a parameter has a default specified, all subsequent parameters must also have a default specified.

– When referencing a template, parameters with default values can be omitted

– if a template parameter is omitted, all subsequent template parameters must also be omitted.

template<typename T1,typename T2=int,int i=23>

class MyClass{};

MyClass<double, string,46> mc1; // specify all parameters MyClass<string,double> mc2; // omit "i"

MyClass<string,double,23> mc3; // same as above MyClass<int> mc4; // all default

MyClass<int,int,0> mc5; // must specify "T2" to specify "i"

(9)

Templates Instantiation

• Two template instantiations refer to the same template if their parameters are all the same

typedef string MyString;

typedef vector<string> T1;

typedef vector<MyString> T2;

T1 vec1;

T2 vec2;

vector<string> vec3;

(10)

Instantiation of Member Functions

• Member functions of class templates are only instantiated if they are referenced.

template <typename T>

class MyClass{

public:

T* makeCopy(T* p){

return p->clone();

}

}; MyClass<int> mci; // OK double d;

MyClass<double> mcd; // OK

double* pd=mcd.makeCopy(&d); // error

(11)

Templates and Static Members

• Each instantiation of the template will have its own private copy of the static members.

template <typename T>

class X {

public: static T s ; } ;

template <typename T> T X<T>::s = 0 ;

Initialization value Member name

member type

It’s a template

(12)

Templates and Friends

template <typename T>

class X {

friend class Y<T>; // Y<T> is friend of X<T> only if they have // the same type parameter

friend class Foo; //class Foo is friend to all instances of X.

template <typename OtherType>

friend class Z<OtherType>;

// All instantiations of Z are friends to all // instantiations of X.

}

(13)

Templates and Inheritance

Templates and inheritance can be related in different ways

– A class template derived from a class template

instantiation template<typename T> class Base{…};

template<typename T> class Derived : public Base<T>{…};

– A class template derived from a non-template class (hoisting)

class Base{…};

template<typename T> class Derived : public Base{…};

– A non-template class derived from a class template

instantiation template<typename T> class Base{…};

class Derived : public Base<ConcreteType>{…};

– Mixins

template<typename T> class Derived : public T {…};

(14)

Mixins

– A mixin is a class designed to provide functionality for another class.

14

template <typename T>

class LoggingClass : public T { public:

void execute(){

cout << “LOG: starting task “ << endl;

T::execute();

cout << “LOG: finishing task “ << endl;

} } ;

LoggingClass<MyClass1>() m1;

MyClass2 m2 = new LoggingClass<MyClass2>();

m1.execute();

static_cast<LoggingClass<MyClass2>>(m2).execute();

As long as a class supports an “execute” method, LoggingClass

can be used to add logging capabilities to the execution.

(15)

Mixins cont.

– Mixins can be used to add any mixture of functionalities to a class:

template <typename T>

class Flying: public T { public:

void fly(){ //do something } } ;template <typename T>

class Swimming: public T { public:

void swim(){ //do something } } ; template <typename T>

class Walking: public T { public:

void walk(){ //do something } } ;

class Animal{

… };

Swimming<Animal> fish;

Swimming<Walking<Animal>> penguin;

Swimming<Walking<Flying<Animal>>> duck;

(16)

Template Constraints

• Constraints on parameters are implicitly imposed

– operations that must work on objects of the appropriate type – class members that must exist

template<typename T>

void func(T& value) {

const T ref = value;

T* p = new T();

*p = ref;

T temp(23);

p->clone();

}

Constrains on T:

1. Cannot be a reference.

2. Must have a copy constructor.

3. Must have a destructor.

4. Must have a default constructor.

5. Must have an assignment Operator.

6. Must have a constructor T(int).

7. Must have member clone().

(17)

Template Specialization

• Allows defining different code for a specific set of template parameters

• Explicit specialization

template<typename T>

struct Printer {

void print(T t) {

cout << "the value is " << t << endl; } };

template<>

struct Printer<int> { void print(int n) {

cout << "the number is " << n << endl; } };

(18)

Compile-time Computations with Explicit Specialization

void foo(){

int x = Factorial<4>::value; // == 24 int y = Factorial<0>::value; // == 1 }

template<int N>

struct Factorial {

enum {value = N*Factorial<N-1>::value; } };

template <>

struct Factorial<0> { enum {value = 1; } };

(19)

Partial Specialization

Specializing for a subset of the template parameters

template <typename T,typename U>

struct SameType {

static const bool result = false;

};

template <typename T>

struct SameType<T,T> {

static const bool result = true;

};

void foo(){

cout<<"Is int the same type as double?" <<

(SameType<int,double>::result?"Yes":"No")<<endl;

cout<<"Is string the same type as string?" <<

(SameType<string,string>::result?"Yes":"No") <<endl;

}

(20)

Meta Operations

template <bool g, typename T, typename E>

struct IF {

typedef T RET;

};

template <typename T, typename E>

struct IF<false, T, E> { typedef E RET;

};

// if sizeof(int) < sizeof(long) then use long else use int IF<sizeof(int)<sizeof(long), long, int>::RET i;

(21)

typename keyword

• Used for denoting qualified, dependent types.

• Is T::something a type or a value?

template <typename T>

struct SameType { int x;

void foo() { T::something * x; } };

template <typename T>

struct SameType { int x;

void foo() { typename T::something * x; } };

A value

A Type

(22)

What Are Type Traits

Think of a trait as a small object whose main purpose is to carry information used by another object or algorithm to determine "policy" or "implementation details".

- Bjarne Stroustrup

(23)

What Are Type Traits?

• Compile-time code that exposes different charactaristics of types

• Can also be used to change types, or the program control flow

• Many Type Traits implementations added in C++

11.

• Under the <type_traits> header

• Type traits are often implemented using template

specialization, but not always.

(24)

Type Traits Examples

24

• Traits for checking type categories:

//generic definition:

template <typename T>

struct is_void{

static const bool value = false;

};

//void specialization:

template <>

struct is_void<void>{

static const bool value = true;

};

//generic definition:

template <typename T>

struct is_pointer{

static const bool value = false;

};

//pointer specialization:

template <typename T>

struct is_pointer <T*>{

static const bool value = true;

};

• Other available categories: is_enum, is_integral,

is_floating_point, is_function, is_abstract …

(25)

Type Traits Examples (cont.)

• Traits can also be used to check for supported operations:

• is_default_constructable, is_assignable, is_destructible

• To retrieve type relationships or qualities:

• is_base_of, is_same, alignment_of

• Or to change types:

• remove_pointer, make_unsigned

(26)

Type Traits Usage

• Example of changing control flow:

struct A{};

template <typename T>

struct someStruct{

void foo(){ //different implementation if A is base of T if (std::is_base_of<A,T>::value)

//do something else

//do something else }};

References

Related documents

Ex 2.2.C: Behavioral Patterns Template Method Ab t t Cl Template Abstract Class Method Primitive Primitive Operations Concrete Class Ex 2.2.C: Behavioral Patterns Template Method.

class, only the public and protected members of base class can be accessed by the member functions of derived class. This means no private member of the base class

Or extend to from most powerful employee schedule maker yet Work done Get an online shift roster planner and create employee schedules. How could Make a Gantt Chart in Google Docs

// DYNAMICALLY LINKED IMPLEMENTATION OF STACK continued // member function definitions for class StackType?.

Vanderbilt University 172 A d v anc ed A C E T utor ia l Do ACE_Message_Queue Class Implementation template &lt;class SYNCH_STRAT&gt; ACE_Message_Queue&lt;SYNCH_S TRA T&gt;:: ACE_

 Private methods of the base class are not accessible to a derived class (unless the derived class is a friend of the base class).  If the subclass is derived

template &lt;typename T&gt; class Stack { public:. Stack

 Private methods of the base class are not accessible to a derived class (unless the derived class is a friend of the base class).  If the subclass is derived