c++ training datascope lawrence d’antonio
DESCRIPTION
C++ Training Datascope Lawrence D’Antonio. Lecture 7 An Overview of C++: What is Polymorphism? – Parametric Polymorphism. What is polymorphism?. Parametric. Universal. Subtype. Polymorphism. Overloading. Ad-hoc. Coercion. - PowerPoint PPT PresentationTRANSCRIPT
![Page 1: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/1.jpg)
C++ TrainingC++ TrainingDatascopeDatascope
Lawrence D’AntonioLawrence D’AntonioLecture 7Lecture 7
An Overview of C++:An Overview of C++:What is Polymorphism? – What is Polymorphism? – Parametric PolymorphismParametric Polymorphism
![Page 2: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/2.jpg)
What is polymorphism?What is polymorphism?
Different types of objects respond to the Different types of objects respond to the same message and use the appropriate same message and use the appropriate method.method.
Polymorphism
Universal
Ad-hoc
Parametric
Subtype
Overloading
Coercion
![Page 3: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/3.jpg)
Parametric Polymorphism
Parametric polymorphism parametrizes Parametric polymorphism parametrizes the object type (e.g., a list class, where the the object type (e.g., a list class, where the type of object stored is parametrized).type of object stored is parametrized).
Parametric polymorphism in C++ is Parametric polymorphism in C++ is implemented as templates.implemented as templates.
Both classes and functions may be Both classes and functions may be templates.templates.
![Page 4: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/4.jpg)
Template Functions
template<class T>
T max(T a, T b) {
return a > b ? a : b;
}
![Page 5: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/5.jpg)
Is this legal?
int a,b = 6;
const int c = 3;
double x,y = 3.2;
a = max(b,4);
a = max(b,c);
x = max(y,3.3);
x = max(b,y);
![Page 6: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/6.jpg)
a = max(b,4); //Legal, max<int,int>a = max(b,c); //Legal, max<int,int>x = max(y,3.3); //Legal, max<double,double>x = max(b,y); //Illegal, no max<int,double>
A template function is called only when there is an exact match for type parameters (only trivial conversions, such as const int to int are allowed). But the following is legal.
x = max<double>(4,4.2);
![Page 7: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/7.jpg)
Better max?template<class S, class T>T max(S a, T b) { return a > b ? a : b;}
main() { int a, b = 3; double x, y = 3.2;
a = max(b,5); x = max(y,5.4); x = max(b,y); x = max(y,b); return 0;}
![Page 8: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/8.jpg)
a = max(b,5); //Legal, returns 5
x = max(y,5.4); //Legal, returns 5.4
x = max(b,y); //Legal, 3.2
x = max(y,b); //Legal, but //returns 3.0!
![Page 9: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/9.jpg)
Best max?template<class R, class S, class T>R max(S a, T b) { return a > b ? a : b;}
main() { int a, b = 3; double x, y = 3.2;
a = max(b,5); x = max(y,5.4); x = max(b,y); x = max(y,b); return 0;}
![Page 10: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/10.jpg)
Doesn’t compile. The function max() is supposed to have 3 template parameters. But each call only uses 2 parameters.
![Page 11: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/11.jpg)
Try this maxtemplate<class R, class S, class T>R max(S a, T b) { return a > b ? a : b;}
main() { int a, b = 3; double x, y = 3.2;
a = max<int>(b,5); x = max<double>(y,5.4); x = max<double>(b,y); x = max<double>(y,b);
return 0;}
![Page 12: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/12.jpg)
Is this legal?
Return back to the original definition of max.
int x = 5, y = 6;
int *p = &x, *q = &y;
int z = max(p,q);
![Page 13: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/13.jpg)
Legal, but probably not what you want.
max(p,q) compares addresses, not data values.
![Page 14: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/14.jpg)
Can we fix this?
template<class T>
T max(T a, T b)
{ return a > b ? a : b; }
template<class T>
T* max<T *a, T *b>
{ return *a > *b ? a : b; }
![Page 15: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/15.jpg)
Should we fix this?
Probably not. Overloading the max function to compare dereferenced pointers means that we can’t compare addresses using max.
![Page 16: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/16.jpg)
STL version of max
template<class T>
const T &max(const T &a, const T &b)
{ return a < b ? b : a; }
![Page 17: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/17.jpg)
Another problem
const char *s = “Hello”;
const char *t = “World”;
std::string s = max(s,t);
std::cout << s;
What does this print out?
Who knows? max returns the char* with the larger memory address.
![Page 18: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/18.jpg)
A Solution
Overload the max function. The second is called a template specialization.
template<class T>
const T& max(const T&a, const T&b)
{ return a < b ? b : a; }
const char* max(const char *a,const char* b)
{ return std::strcmp(a,b) < 0 ? b : a; }
![Page 19: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/19.jpg)
STL Solution
template<class T>
const T& max(const T&a, const T&b)
{ return a < b ? b : a; }
template<class T, class BinPred>
const T& max(const T&a, const T&b, BinPred comp)
{ return comp(a,b) ? b : a; }
![Page 20: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/20.jpg)
Using a predicate
bool comp(const char *a, const char *b)
{
return std::strcmp(a,b) < 0;
}
const char *s = “Hello”;
const char *t = “World”;
std::string s = max(s,t,comp);
![Page 21: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/21.jpg)
Functor solution
class Comp {
public:
bool operator()(const char *a,
const char *b)
{ return std::strcmp(a,b) < 0; }
};
const char *s = “Hello”;
const char *t = “World”;
std::string s = max(s,t,Comp());
![Page 22: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/22.jpg)
Is this legal?
std::string s1(“apple”);
std::string s2(“tomato”);
std::max(“apple”,”peach”);
std::max(“apple”,”tomato”);
std::max(“apple”,s1);
std::max(s1,s2);
![Page 23: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/23.jpg)
std::max(“apple”,”peach”);//Legal, both arguments are const char[5]
std::max(“apple”,”tomato”);//Illegal, arguments are different types
std::max(“apple”,s1);//Illegal, arguments are different types
std::max(s1,s2);//Legal, both arguments are type string
![Page 24: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/24.jpg)
Is this legal?template<class T>T foo(){ return T(); }
template<class T>void bar(){ T t;
}
main() { int x = foo(); bar();
return 0;}
![Page 25: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/25.jpg)
Not legal for two reasons.
int x = foo();
Illegal because the compiler doesn’t know which version of foo() to call. It won’t determine that foo() should return an int by looking at the LHS.
bar();
Illegal because the compiler doesn’t know which version of bar() to call.
![Page 26: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/26.jpg)
Legal version of exampletemplate<class T>T foo(){ return T(); }
template<class T>void bar(){ T t;
}
main() { int x = foo<int>(); bar<int>();
return 0;}
![Page 27: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/27.jpg)
Template name lookup
Template name resolution involves what is known as “two-phase name lookup”.
Template names are divided into two categories: dependent and non-dependent names.
Dependent and non-dependent names are resolved at different times.
![Page 28: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/28.jpg)
Dependent names
Dependent names have definitions that depend on template parameters, but have no declaration within the template definition.
Dependent names are only resolved at the time of instantiation.
![Page 29: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/29.jpg)
Non-dependent names
Non-dependent names are names that don’t depend on a template parameter, the name of the template itself, and names declared within it (members, friends, and local variables).
![Page 30: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/30.jpg)
Exampletemplate<class T>class X {
T t;public:
X(const T &a):t(a) { t.init(); }
template<class U>T foo() {
U u = t.begin();return *u;
}};
![Page 31: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/31.jpg)
Name resolution in example
Non-dependent names
X, t, a, X(const T &), foo(), U,
u
Dependent names
T::init(), T::begin()
![Page 32: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/32.jpg)
SFINAE
“Substitution failure is not an error.” When examining which template function
to call from a set of overloaded template functions, there is no error if some substitutions are illegal.
![Page 33: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/33.jpg)
Exampletemplate<class Func, class T>void apply(Func f, T x){ f(x); }
template <class T>void multi(T) { }
template <class T*>void multi(T *) { }
main() {apply(multi<int>,5);return 0;
}
![Page 34: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/34.jpg)
apply(multi<int>,5) calls multi(T) with int substituting for T. The failure of the substitution of int in multi(T*) does cause an error.
![Page 35: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/35.jpg)
Is this legal?
template<int N>int g() { return N; }
template<int *P>int g() { return *P; }
main(){ return g<1>();}
![Page 36: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/36.jpg)
Yes, this is legal (if odd looking). g<1> binds to g<int>, the failure to bind to g<int *> is not an error.
![Page 37: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/37.jpg)
Is this legal?
template <class Alloc>
class container_helper
{
typedef Alloc::value_type value_type;
};
![Page 38: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/38.jpg)
Not legal, the compiler has no idea what the dependent name Alloc::value_type represents. Here is the correct version.
template <class Alloc>class container_helper{
typedef typename Alloc::value_type value_type;};
![Page 39: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/39.jpg)
Is this legal?
template <class Alloc>
class container_helper
{
typedef typename Alloc::value_type
value_type;
typedef
std::pair<value_type,value_type> element_type;
};
![Page 40: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/40.jpg)
Yes, this is legal.
typedef std::pair<value_type,value_type>
element_type;
This can be resolved in scope.
![Page 41: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/41.jpg)
Is this legal?
template <class Alloc>
class container_helper
{
typedef typename Alloc::value_type
value_type;
typedef
std::pair<value_type,value_type> element_type;
typedef typename
Alloc::rebind<element_type>::other
element_allocator;
};
![Page 42: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/42.jpg)
Not legal, perhaps surprisingly. The compiler cannot determine from
Alloc::rebind<element_type>::other
what rebind refers to (is it an object, a function, or Superman?).
![Page 43: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/43.jpg)
ADL
Argument-dependent lookup applies to unqualified names where it appears that a nonmember function is being called.
ADL proceeds by looking up a name in namespaces and classes associated with the types of the function call arguments.
![Page 44: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/44.jpg)
Which functions are called?#include <iostream>
namespace X { template <class T> void f(T) { std::cout << "f<T>\n"; }}
namespace N { using namespace X; enum E{ e1 }; void f(E) { std::cout << "f(E)\n"; }}
void f(int) { std::cout << "f(int)\n"; }
main() { ::f(N::e1); f(N::e1); return 0;}
![Page 45: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/45.jpg)
::f(N::e1);//Qualified name, so calls global f, no ADL used
f(N::e1);//Calls N::f. The call argument N::e1 is associated //with namespace N. So this means that N::f is //preferred over ::f. Note that X::f is not considered, //because using directives are ignored in ADL.
![Page 46: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/46.jpg)
Is this legal?
template<typename T,
typename Alloc = std::allocator<T> > class my_container : private
container_helper<Alloc>::element_allocator
{
//...
};
![Page 47: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/47.jpg)
Perhaps surprisingly this is legal. The dependent name
container_helper<Alloc>::element_allocator
cannot be resolved,. But since it is being used as a base class, the compiler is happy.
![Page 48: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/48.jpg)
What is rebind?
A template typedef.template <class T> class allocator { . . . template <class U> struct rebind { typedef allocator<U> other; }; ... template <class U> allocator(const allocator<U>&);
};
![Page 49: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/49.jpg)
Use of rebind
template <class T, class Allocator = allocator<T> >
class list {
private:
typedef . . . listnode;
typedef typename Allocator::rebind<listnode>::other
Node_allocator;
Node_allocator alloc_;
list_node* make_node()
{ return new(alloc_.allocate(1)) list_node; }
public:
list(const Allocator& a = Allocator()) : alloc_(a) { } // implicit conversion . . .
};
![Page 50: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/50.jpg)
Template classes
The declaration and definition of a template class “must” be in the same header file.
![Page 51: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/51.jpg)
For example
//stack.h
template <class T>
class Stack {
public:
T pop();
};
![Page 52: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/52.jpg)
//stack.cpp
#include “stack.h”
template <class T>
T Stack<T>::pop()
{
//...
}
![Page 53: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/53.jpg)
//main.cpp
#include “stack.h”
main() {
Stack<int> si;
//Push elements onto si
int x = si.pop(); //Illegal!
![Page 54: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/54.jpg)
What happened?
No function Stack<int>::pop() defined.
When stack.cpp compiled, no definition for Stack<T> is created. This is because no instantiations exist.
Since main.cpp uses Stack<int>, the compiler instantiates a definition for Stack<int>, but not for the member functions in Stack.cpp!
![Page 55: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/55.jpg)
Can we fix this?
export keyword
//stack.h
export template <class T>
class Stack {
public:
T pop();
};
![Page 56: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/56.jpg)
What does this do?
The keyword export allows the programmer to put template declarations and template definitions in different translation units.
PROBLEM: Few compilers implement export!
![Page 57: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/57.jpg)
Another solution
Explicit instantiation. It requires knowledge of what template instantiations are needed in main.
![Page 58: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/58.jpg)
Example
//stack.h
#ifndef STACK_H#define STACK_H
template <class T>class Stack {public: T pop();};
#endif
![Page 59: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/59.jpg)
//mystackdef.h
#ifndef MYSTACKDEF_H#define MYSTACKDEF_H
#include <iostream>#include "mystack.h"
template <class T>T Stack<T>::pop() { std::cout << "Pop\n"; return T();}
#endif
![Page 60: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/60.jpg)
//mystackinst.cpp
#include "mystackdef.h"#include <string>
template class Stack<int>;
template std::string Stack<std::string>::pop();
![Page 61: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/61.jpg)
//main.cpp
#include "mystack.h"#include <string>
main() { Stack<int> s; Stack<std::string> t;
s.pop(); t.pop(); return 0;}
![Page 62: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/62.jpg)
Does that work?
Yes, it works. But it is a burden on the programmer. They must see what specific instantiations are needed in the program.
![Page 63: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/63.jpg)
Nontype template parameterstemplate <class T, int N>class Stack{ T arr[N]; int count;public: Stack(): count(0) {} void push(const T &t);};
template <class T, int N>void Stack<T,N>::push(const T &t){ if (count != N) arr[count++] = t;}
![Page 64: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/64.jpg)
Is this legal?
main() { Stack<int,10> stack10; Stack<int,20> stack20;
stack10.push(8); stack10.push(-3); stack20.push(11); stack20.push(0); stack20 = stack10; return 0;}
![Page 65: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/65.jpg)
Not legal.
stack20 = stack10;
Assignment between Stacks of different types.
![Page 66: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/66.jpg)
Is this legal?#include <algorithm>#include <vector>#include <list>
template <class T, int x>T add_val(const T &t){ return t+x; }
main() { std::vector<int> v; std::list<int> l(2);
v.push_back(5); v.push_back(8); std::transform(v.begin(),v.end(),
l.begin(), add_val<int,10>); return 0;}
![Page 67: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/67.jpg)
Yes, this is legal.
std::transform copies from vector v to list l, applying the function add_val<int,10> to each element being copied.
![Page 68: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/68.jpg)
Nontype parameter Rules
A nontype parameter must be one of the following types:
An integer or enumeration type A pointer type A reference type
![Page 69: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/69.jpg)
Is this legal?
int C
class C;
int X;
template <class T>
class X;
struct S;
template <class T>
class S;
![Page 70: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/70.jpg)
int Cclass C; //Legal, class and nonclass names
//live in different spaces
int X;template <class T>class X; //Illegal, name conflict
struct S;template <class T>class S; //Illegal name conflict
![Page 71: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/71.jpg)
Template Linkage
Class names can be the same as nonclass names
Class templates cannot share names with other program constructs. Templates have linkage, but not “C” linkage.
![Page 72: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/72.jpg)
Is this legal?
template <class T>
class Foo {
public:
virtual ~Foo();
template <class U>
virtual void bar(const U&);
};
![Page 73: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/73.jpg)
virtual ~Foo(); //Legal, one copy per Foo<T> //instance
template <class U>virtual void bar(const U&);//Illegal, unknown number of versions of//bar() per Foo<T> instance
Conclusion: Member function templates cannot be virtual.
![Page 74: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/74.jpg)
Is this legal?template <class T>class Foo {private: T t;public: Foo(T s):t(s) { } T get() const { return t; } template<class U> Foo<T> operator=(const Foo<U> &x) { if ( (void *) this == (void *) &x ) return *this; t = x.get();
return *this; }};
![Page 75: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/75.jpg)
What functions are called?
main() { Foo<int> f1(4); Foo<double> f2(5.4); f2 = f1;
Foo<int> f3(6); f1 = f3; return 0;}
![Page 76: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/76.jpg)
Foo<int> f1(4); //ctorFoo<double> f2(5.4); //ctorf2 = f1; //User defined operator=
Foo<int> f3(6); //ctorf1 = f3; //Compiler defined operator=
![Page 77: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/77.jpg)
Template vs. Nontemplate#include<iostream>
template<class T>void f(T){ std::cout << "Template\n"; }
void f(int){ std::cout << "Nontemplate\n"; }
main(){ f(7); f('a'); return 0;}
![Page 78: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/78.jpg)
f(7);//Calls f(int), in general the nontemplate //version will be preferred
f('a');//Calls f<char>(char), prefers an exact match
![Page 79: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/79.jpg)
Template template parameters
template <typename T,
template <typename U,
typename ALLOC = std::allocator<U> >
class CONT = std::deque>
class Stack {
private:
CONT<T> c;
public:
void push(const T &t);
void pop();
T top() const;
![Page 80: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/80.jpg)
template <typename T2,
template < typename U,
typename = std::allocator<U> >
class CONT2 = std::deque>
Stack<T,CONT> &operator=(Stack<T2,CONT2> const &s) {
if ((void *)this == (void *)&s) {
return *this
}
Stack<T2,CONT2> tmp(s);
c.clear();
while (!tmp.empty()) {
c.push_front(tmp.top());
tmp.pop();
}
return *this;
}
};
![Page 81: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/81.jpg)
Usage
Stack<int> a;
Stack<float> b;
// . . .
b = a;
Stack<int,vector<int> > c;
Stack<float,vector<float> > d;
// . . .
d = c;
![Page 82: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/82.jpg)
Is this legal?
class X { };
list<::X> what;
![Page 83: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/83.jpg)
Not legal.
list<::X> what;
//This is the same as
list[:X> what;
//<: is a digraph that is the same as
//a [
![Page 84: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/84.jpg)
Correct version
list< ::X> what;
![Page 85: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/85.jpg)
Template Argument Deduction
First, template parameters are deduced from the argument types in a function call
Next, if all parameters can be correctly deduced from the argument types then these types are used in the rest of the function declaration.
If either step above fails then a substitution failure occurs (but only an error if all substitutions fail).
![Page 86: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/86.jpg)
Exampletemplate<class T>typename T::value_type at(const T &a, int i){ return a[i]; }
void f(int *p){ at(p,0); } void g(int *p){ at<int*>(p,0); }
main(){ int a[3];
f(a); g(a); return 0;}
![Page 87: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/87.jpg)
This is clearly illegal.
Invoid f(int *p){ at(p,0); }
There is no matching function at(int *&,int)
Invoid g(int *p){ at<int*>(p,0); }
There is no matching function at(int *&,int)
![Page 88: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/88.jpg)
Argument-parameter matching
Suppose an actual type A is matched to a parameter type T.
If the argument parameter is a reference then P is the type referenced and A is the type of the argument.
Otherwise P is the declared parameter type and A is determined by decaying types (e.g., arrays go to pointers, const and volatile are ignored).
![Page 89: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/89.jpg)
What type is T?template<class T>void f(T) {}
template<class T>void g(T&) {}
main() { double x[20]; const int y = 3;
f(x); g(x); f(y); g(y); f(3); g(3);
return 0;}
![Page 90: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/90.jpg)
f(x); // nonreference parameter, T is double*
g(x); // reference parameter, T is double[20]
f(y); // nonreference parameter, T is int
g(y); // reference parameter, T is const int
f(3); // nonreference parameter, T is int
g(3); // reference parameter, ERROR, 3 is not int&
![Page 91: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/91.jpg)
Deduced Contexts
Complex type declarations are built up from elementary constructs.
Matching proceeds from the top level construct and recurses through the composing elements.
Type declarations matched in this way are called deduced contexts.
Qualified type names, e.g., Q<T>::X cannot be used to deduce T.
![Page 92: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/92.jpg)
What are the deduced types?template<class T>void f1(T*) {}
template<class T, int N>void f2(T(&)[N]) {}
template<class T1, class T2, class T3>void f3(T1 (T2::*)(T3*)) {}
struct S { void f(double *) {}};
void g(int ***p){ bool b[42]; f1(p); f2(b); f3(&S::f);}
![Page 93: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/93.jpg)
f1(p); //T is int**
f2(b); //E is bool, N is 42
f3(&S::f); //T1 is void, T2 is S, T3 is double
![Page 94: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/94.jpg)
Is this legal?template<int N>class X {public: typedef int I; void f(int) {}};
template<int N>void fppm(void (X<N>::*)(X<N>::I)) {}
main() { fppm(&X<33>::f);
return 0;}
![Page 95: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/95.jpg)
No,
The compiler cannot determine the type of the qualified expression
X<N>::I
![Page 96: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/96.jpg)
OK, is this legal?template<int N>class X {public: typedef int I; void f(int) {}};
template<int N>void fppm(void (X<N>::*)(typename X<N>::I)) {}
main() { fppm(&X<33>::f);
return 0;}
![Page 97: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/97.jpg)
Yes, this is legal (but complicated).
How does it match types in the expression?
fppm(&X<33>::f);
X<N>::I is a nondeduced context, but the compiler can use the deduced context X<N>::* to determine the parameter N and then plug that into the nondeduced context.
![Page 98: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/98.jpg)
Is this legal?template<class T>class B {};
template<class T>class D: public B<T>{};
template<class T>void f(B<T> *) {}
template<class T>void g(D<T> d) { f(&d);}
![Page 99: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/99.jpg)
Yes this is legal.
f(&d) is legal because a D<T> can be converted to a B<T>
![Page 100: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/100.jpg)
Which template is used?
template<class T>
void f(T) {}
template<class T>
void f(T*) {}
main() {
f(0);
f((int*)0);
}
![Page 101: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/101.jpg)
f(0); //Calls f<int>(int)
f((int*)0); //Has two possibilities//f<int*>(int*) or f<int>(int*)//The second function is considered//the “more specialized”
![Page 102: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/102.jpg)
More specialized templates
In the previous example, consider possible argument types A1, A2*
A2* can match f<T>(T) (with T = A2*) or can match f<T>(T*) (with T = A2).
But A1 can only match f<T>(T) (with T = A1).
Hence f<T>(T*) is more specialized.
![Page 103: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/103.jpg)
Full Class Specializationtemplate<class T>class Types {public: typedef int I;};
template<class T, class U = class Types<T>::I>class S;
template<>class S<void> { };
template<> class S<char,char>;
template<> class S<char,0>;
![Page 104: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/104.jpg)
main() { S<int>* psi; S<int> si; S<void>* psv; S<void,int> svi; S<void,char> svc; S<char,char> scc; return 0;}
template<>class S<char,char> {};
![Page 105: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/105.jpg)
Which are legal?
template<>
class S<void> { };
//Legal, T = void, U = Types<void>::I
template<> class S<char,char>;
//Legal. T = char, U = char
template<> class S<char,0>;
//Illegal, T = char, but 0 is not a U
![Page 106: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/106.jpg)
Which are legal?
S<int>* psi;
//Legal, uses S<T,U>, no definition needed
S<int> si;
//Illegal, uses S<T,U> but no definition //available
S<void>* psv;
//Legal, uses S<void>
![Page 107: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/107.jpg)
Which are legal?
S<void,int> svi;
//Legal, uses S<void>, definition available
S<void,char> svc;
//Illegal, uses S<T,U>, no definition
S<char,char> scc;
//Illegal, no definition available
![Page 108: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/108.jpg)
Is this legal?
template<>class S<char**> { public: void foo() const;};
template<>void S<char**>::foo() const{ }
![Page 109: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/109.jpg)
Not legal.
template<>void S<char**>::foo() const{ }
This is an “invalid function declaration”.
Correct syntax is
void S<char**>::foo() const{ }
![Page 110: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/110.jpg)
Is this legal?template<class T>class Outside {public: template<class U> class Inside {};};
template<>class Outside<void> {public: template<class U> class Inside { static int x; };};
template<class U>int Outside<void>::Inside<U>::x = 1;
![Page 111: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/111.jpg)
(1) It’s okay that Outside<T>::Inside<U> and Outside<void>::Inside<U> are completely unrelated.
(2) A template class can have static members. Each instance of the class has it’s own version of the static member.
(3) The definition of Inside<U>::x is not preceded by template<>
![Page 112: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/112.jpg)
Is this legal?
class Invalid {};
Invalid<double> x;
template<>
class Invalid<double>;
![Page 113: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/113.jpg)
Not legal.
Specialization of Invalid<double> after instantiation.
![Page 114: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/114.jpg)
Is this legal?#include<iostream>
template<class T>int f(T, T x = 42) { return x; }
template<>int f(int, int = 35) { return 0; }
template<class T>int g(T, T x = 42) { return x; }
template<>int g(int, int y) { return y/2; }
main() { std::cout << g(0) << '\n'; return 0;}
![Page 115: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/115.jpg)
Not legal. A template function specialization cannot include default argument values.
template<class T>int f(T, T x = 42) { return x; }
template<>int f(int, int = 35) { return 0; }
![Page 116: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/116.jpg)
Explicit Specialization
Member templates, static data members, and member functions of class templates may be specialized.
![Page 117: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/117.jpg)
Is this legal?#include <iostream>
template<class T>class Foo { static int x;public: void bar() { std::cout << "Where am I?\n"; }};
template<class T>int Foo<T>::x = 4;
template<>int Foo<int>::x;
template<>void Foo<bool>::bar();
main() { return 0; }
![Page 118: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/118.jpg)
This is legal (perhaps surprisingly).
Static members and member functions can be given different definitions for specialized classes.
Nondefining out-of-class declarations are allowed for member functions or static data members.
![Page 119: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/119.jpg)
Is this legal?#include <iostream>
template<class T>class Foo { static int x;public: void bar() { std::cout << " Where am I?\n"; }}; template<class T> int Foo<T>::x = 4;
template<>class Foo<void> { double y;public: void bar() { std::cout << x << (y = 3.415) << '\n'; }};
main() { Foo<void> fv; fv.bar();
return 0;}
![Page 120: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/120.jpg)
Illegal.
Foo<void> does not have a data member x.
![Page 121: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/121.jpg)
Is this legal?template<class T>class Foo { static int x;public: void bar() { std::cout << "Where am I?\n"; }}; template<class T> int Foo<T>::x = 4;
template<> int Foo<int>::x; template<> void Foo<bool>::bar();
main() { Foo<int> fi; fi.bar(); Foo<bool> fb;
}
![Page 122: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/122.jpg)
Foo<int> fi;//Legal, Foo<int> doesn’t need to define//static int x
fi.bar();//Legal, Calls Foo<T>::bar()
Foo<bool> fb;//Legal, Foo<bool> doesn’t need to define//member function bar()
![Page 123: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/123.jpg)
Example
template<class T>class Outer {public: template<class U> class Inner { private: static int count; };};
![Page 124: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/124.jpg)
Is this legal?template<>int Outer<void>::Inner::count = 7;
template<>template<>int Outer<void>::Inner<char>::count = 7; template<>template<>class Outer<int>::Inner<double> {public: enum { ecount = 1 }; Inner() { std::cout << "Inner<double>\n"; }};
![Page 125: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/125.jpg)
template<>int Outer<void>::Inner::count = 7;//Not legal. Inner must have a type.
template<>template<>int Outer<void>::Inner<char>::count = 7;//Legal, but template classes have explicit//specialization template<>template<>class Outer<int>::Inner<double> { }//Legal, Inner allowed to be redefined.
![Page 126: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/126.jpg)
Is this legal?
template<>template<class T>class Outer<char *>::Inner {public: static long count; };
template<>template<class T>long Outer<char *>::Inner<T>::count = 6L;
![Page 127: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/127.jpg)
template<>template<class T>class Outer<char *>::Inner {}//Not legal, Inner should be Inner<T>
template<>template<class T>long Outer<char *>::Inner<T>::count = 6L;//Legal, Inner<T> allowed to define count
![Page 128: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/128.jpg)
Is this legal?
template<class T>
template<>
class Outer<T>::Inner<void>;
![Page 129: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/129.jpg)
Not legal.
template<> cannot follow after a template parameter list.
![Page 130: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/130.jpg)
Is this legal?template<class T = float, int i = 5> class A { public: A() {} };
template<> class A<> { public: A() {} };
main() {A<int,6> x; A<> y;
return 0;}
![Page 131: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/131.jpg)
A<int,6> x; //Legal, T = int, i = 6
A<> y;//Legal, uses default arguments, //T = float, i = 5
![Page 132: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/132.jpg)
Partial Specializationtemplate<class T>class List {}; //Primary template
template<class T>class List<T*> { //Partial specializationprivate: List<void*> impl;public: void append(T* p) { impl.append(p); }};
template<>class List<void*> { //Full specializationpublic: void append(void *p) { ... }};
![Page 133: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/133.jpg)
Further specializationstemplate<class C>class List<void * C::*> {//Partial specializationpublic: typedef void * C::* ElementType; void append(ElementType pm);};
template<class T, class C>class List<T * C::*> { //Partial specializationprivate: List<void* C::*> impl;public: typedef T* C::* ElementType void append(ElementType pm) { impl.append( (void* C::*)pm); }};
![Page 134: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/134.jpg)
Partial Specialization Rules
The arguments of the partial specialization must match in kind (type, nontype, template) with the correspnding parameters of the primary template.
No default arguments. Nontype arguments must be
nondependent or plain (no expressions) Argument list must be different from the
primary template.
![Page 135: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/135.jpg)
Exampletemplate<class T, int i = 3>class S; //primary template
template<class T>class S<int, T>; //Illegal, parameter mismatch template<class T = int>class S<T,10>; //Illegal, no default arguments
template<int I>class S<int, I*2>; //Illegal, no nontype expressions
template<class U, int W>class S<U,W>; //Illegal, same as primary template
![Page 136: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/136.jpg)
Template Error Messages#include <list>#include <string>#include <functional>#include <algorithm>
main() { std::list<std::string> l;
l.push_back("Hello"); l.push_back("World"); std::list<std::string>::iterator pos;
pos = find_if(l.begin(), l.end(), std::bind2nd(std::greater<int>(),"A"));
return 0;}
![Page 137: C++ Training Datascope Lawrence D’Antonio](https://reader036.vdocuments.net/reader036/viewer/2022062518/56814bf0550346895db8d808/html5/thumbnails/137.jpg)
/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h: In function `_InputIterator std::find_if(_InputIterator, _InputIterator, _Predicate, std::input_iterator_tag) [with _InputIterator = std::_List_iterator<std::string>, _Predicate = std::binder2nd<std::greater<int> >]':/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:336: instantiated from `_InputIterator std::find_if(_InputIterator, _InputIterator, _Predicate) [with _InputIterator = std::_List_iterator<std::string>, _Predicate = std::binder2nd<std::greater<int> >]'error.cpp:14: instantiated from here/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.5/../../../../include/c++/3.4.5/bits/stl_algo.h:187: error: no match for call to `(std::binder2nd<std::greater<int> >) (std::basic_string<char, std::char_traits<char>, std::allocator<char> >&)'/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.5/../../../../include/c++/3.4.5/bits/stl_function.h:440: note: candidates are: typename _Operation::result_type std::binder2nd<_Operation>::operator()(const typename _Operation::first_argument_type&) const [with _Operation = std::greater<int>]/opt/csw/gcc3/lib/gcc/sparc-sun-solaris2.8/3.4.5/../../../../include/c++/3.4.5/bits/stl_function.h:446: note: typename _Operation::result_type std::binder2nd<_Operation>::operator()(typename _Operation::first_argument_type&) const [with _Operation = std::greater<int>]