---------------
template<typename T>
void f(T);

template<typename T>
class X {
    //...
};

f(1);                  // T drog dedukcji zostanie zamieniony na int
f<double>(1);          // T to double
f<complex<double>>(1); // T to complex<double>

X<double> x1;          // T to double
X<complex<double>> x2; // T to complex<double>
---------------
vector<double> x1;          // wektor wartoci typu double
vector<complex<double>> x2; // wektor wartoci typu complex<double>
---------------
class X {
    class M { /*...*/};
    //...
    void mf();
};

void f()
{
    struct S { /*...*/};
    vector<S> vs;    // OK
    vector<X::M> vm; // bd: skadowa X::M jest prywatna
    //...
}

void X::mf()
{
    vector<S> vs; // bd: brak S w zakresie
    vector<M> vm; // OK
    //...
}
---------------
template<typename T, int max>
class Buffer {
    T v[max];
public:
    Buffer() { }
    //...
};

Buffer<char,128> cbuf;
Buffer<int,5000> ibuf;
Buffer<Record,8> rbuf;
---------------
template<typename T, char* label>
class X {
    //...
};

X<int,"BMW323Ci"> x1; // bd: litera acuchowy argumentem szablonu
char lx2[] = "BMW323Ci";
X<int,lx2> x2;        // OK: lx2 ma zewntrzne czenie
---------------
constexpr int max = 200;
void f(int i)
{
    Buffer<int,i> bx;   // bd: powinno by wyraenie stae
    Buffer<int,max> bm; // OK: wyraenie stae
    //...
}
---------------
template<typename T, int max>
class Buffer {
    T v[max];
public:
    Buffer(int i) { max = i; } // bd: prba przypisania do argumentu wartociowego szablonu
    //...
};
---------------
template<typename T, T default_value>
class Vec {
    //...
};

Vec<int,42> c1;
Vec<string,""> c2;
---------------
template<typename T, T default_value = T{}>
class Vec {
    //...
};

Vec<int,42> c1;
Vec<int> c11;      // default_value to int{}, czyli 0
Vec<int*,&foo> c2; // dla jakiej globalnej zmiennej foo
Vec<string> c22;   // default_value to int*{}, czyli nullptr
---------------
template<typename Key, typename V>
class map {
    //...
};
---------------
template<typename Key, typename V, bool(*cmp)(const Key&, const Key&)>
class map {
public:
    map();
    //...
};
---------------
bool insensitive(const string& x, const string& y)
{
    // nie rozrnia wielkoci liter (np. "cze" to to samo co "Cze")
}

map<string,int,insensitive> m; // porwnuje przy uyciu funkcji insensitive()
---------------
template<typename Key, typename V, typename Compare = std::less<Key>>
class map {
public:
    map() { /*...*/}                  // uywa domylnego porwnywania
    map(Compare c) :cmp{c} { /*...*/} // przesania domylne
    //...
    Compare cmp {};                // domylne porwnywanie
};
---------------
map<string,int> m1;                      // uywa domylnego porwnywania (less<string>)

map<string,int,std::greater<string>> m2; // porwnuje przy uyciu greater<string>()
---------------
Complex_compare f3 {"Francuski",3};      // tworzy obiekt porwnawczy (25.2.5)
map<string,int,Complex_compare> m3 {f3}; // porwnuje przy uyciu f3()
---------------
using Cmp = bool(*)(const string&,const string&);
map<string,int,Cmp> m4 {insensitive};    // porwnuje przy uyciu wskanika do funkcji

map<string,int,Cmp> m4 {[](const string& a, const string& b) { return a>b; } };
---------------
map<string, int, [](const string& x, const string& y) const { return x<y; }> c3; // bd
---------------
auto cmp = [](const string& x, const string& y) const { return x<y; }
map<string,int,decltype(cmp)> c4 {cmp};
---------------
template<typename T, template<typename> class C>
class Xrefd {
    C<T> mems;
    C<T*> refs;
    //...
};

template<typename T>
    using My_vec = vector<T>;  // uywa konstruktora domylnego

Xrefd<Entry,My_vec> x1;        // zapisuje odniesienia dla wpisw w wektorze

template<typename T>
class My_container {
    //...
};

Xrefd<Record,My_container> x2; // zapisuje odniesienie dla rekordw w kontenerze My_container
---------------
template<typename C, typename C2>
class Xrefd2 {
    C mems;
    C2 refs;
    //...
};

Xrefd2<vector<Entr y>,set<Entr y*>> x;
---------------
template<typename Key, typename V, typename Compare = std::less<Key>>
class map {
public:
    explicit map(const Compare& comp ={});
    //...
};

map<string,int> m1;              // uyje less<string> do porwnywania
map<string,int,less<string>> m2; // ten sam typ co m1

struct No_case {
// definicja funkcji operator()() do porwnywania acuchw bez rozrniania wielkoci znakw
};
map<string,int,No_case> m3;      // m3 jest innego typu ni m1 i m2
---------------
map<string,int,Complex_compare> m {Complex_compare{"Francuski",3}};
---------------
void f1(int x = 0, int y);     // bd: domylny argument nie jest na kocu
void f2(int x = 0, int y = 1); // OK

f2(,2); // bd skadni
f2(2);  // wywouje f2(2,1);

template<typename T1 = int, typename T2>
class X1 { // bd: domylny argument nie jest na kocu
    //...
};

template<typename T1 = int, typename T2 = double>
class X2 { // OK
    //...
};

X2<,float> v1; // bd skadni
X2<float> v2;  // v2 to X2<float,double>
---------------
template<typename Target =string, typename Source =string>
Target to(Source arg)  // konwertuje Source na Target
{
    stringstream interpreter;
    Target result;

    if (!(interpreter << arg)               // zapisuje arg do strumienia
        || !(interpreter >> result)         // odczytuje result ze strumienia
        || !(interpreter >> std::ws).eof()) // co pozostao w strumieniu?
        throw runtime_error{"Bd to<>()"};

    return result;
}
---------------
auto x1 = to<string,double>(1.2);  // wszystko bezporednie (i rozwleke)
auto x2 = to<string>(1.2);         // Source to drog dedukcji double
auto x3 = to<>(1.2);               // Target to domylnie string; Source to drog dedukcji double
auto x4 = to(1.2);                 // nawias <> jest niepotrzebny
---------------
template<typename T>
class Vector { // oglny typ wektorowy
    T* v;
    int sz;
public:
    Vector();
    explicit Vector(int);

    T& elem(int i) { return v[i]; }
    T& operator[](int i);

    void swap(Vector&);
    //...
};

Vector<int> vi;
Vector<Shape*> vps;
Vector<string> vs;
Vector<char*> vpc;
Vector<Node*> vpn;
---------------
template<>
class Vector<void*>{ // kompletna specjalizacja
    void** p;
    //...
    void*& operator[](int i);
};
---------------
Vector<void*> vpv;
---------------
template<typename T>
class Vector<T*> : private Vector<void*>{ // czciowa specjalizacja
public:
    using Base = Vector<void*>;

    Vector() {}
    explicit Vector(int i) : Base(i) {}

    T*& elem(int i) { return reinterpret_cast<T*&>(Base::elem(i)); }
    T*& operator[](int i) { return reinterpret_cast<T*&>(Base::operator[](i)); }

    //...
};
---------------
Vector<Shape*> vps; // <T*> to <Shape*>, a wic T to Shape
Vector<int**> vppi; // <T*> to <int**>, a wic T to int*
---------------
template<typename T>
class complex {
public:
    complex(const T& re = T{}, const T& im = T{});
    complex(const complex&);         // konstruktor kopiujcy
    template<typename X>
        complex(const complex<X>&);  // konwersja z complex<X> na complex<T>

    complex& operator=(const complex&);
    complex<T>& operator=(const T&);
    complex<T>& operator+=(const T&);
    //...
    template<typename X>
        complex<T>& operator=(const complex<X>&);
    template<typename X>
        complex<T>& operator+=(const complex<X>&);
    //...
};
---------------
template<>
class complex<float> {
public:
    //...
    complex<float>& operator= (float);
    complex<float>& operator+=(float);
    //...
    complex<float>& operator=(const complex<float>&);
    //...
};
---------------
template<>
class complex<double> {
public:
    constexpr complex(double re = 0.0, double im = 0.0);
    constexpr complex(const complex<float>&);
    explicit constexpr complex(const complex<long double>&);
    //...
};
---------------
template<typename T, int N>
class Matrix;       // n-wymiarowa macierz elementw typu T

template<typename T>
class Matrix<T,0> { // specjalizacja dla N==0
    T val;
    //...
};

template<typename T>
class Matrix<T,1> { // specjalizacja dla N=1
    T* elem;
    int sz;         // liczba elementw
    //...
};

template<typename T>
class Matrix<T,2> { // specjalizacja dla N=2
    T* elem;
    int dim1;       // liczba wierszy
    int dim2;       // liczba kolumn
    //...
};
---------------
template<typename T>
class List<T*>{
    //...
};

template<typename T>
class List { // bd: szablon podstawowy za specjalizacj
    //...
};
---------------
template<typename T>
class List {
static_assert(Regular<T>(),"List<T>: T musi by regularny");
    //...
};
---------------
template<typename T>
class List; // nie definicja

template<typename T>
class List<T*>{
    //...
};
---------------
template<typename T>
class List {
    //...
};

List<int*> li;

template<typename T>
class List<T*>{ // bd: uycie specjalizacji przed definicj
    //...
};
---------------
template<typename T>
    class Vector;        // oglna; szablon podstawowy
template<typename T>
    class Vector<T*>;    // specjalizacja dla wszystkich wskanikw
template<>
    class Vector<void*>; // specjalizacja dla void*
---------------
template<typename T>
bool less(T a, T b)
{
    return a<b;
}

template<typename T>
void sort(Vector<T>& v)
{
    const size_t n = v.size();

    for (int gap=n/2; 0<gap; gap/=2)
        for (int i=gap; i!=n; ++i)
            for (int j=i-gap; 0<=j; j-=gap)
                if (less(v[j+gap],v[j]))
                    swap(v[j],v[j+gap]);
}
---------------
template<>
bool less<const char*>(const char* a, const char* b)
{
    return strcmp(a,b)<0;
}
---------------
template<>
bool less<>(const char* a, const char* b)
{
    return strcmp(a,b)<0;
}
---------------
template<>
bool less(const char* a, const char* b)
{
    return strcmp(a,b)<0;
}
---------------
bool less(const char*a, const char*b)
{
    return strcmp(a,b)<0;
}
---------------
template<typename T> T max_value();          // brak definicji

template<> constexpr int max_value<int>() { return INT_MAX; }
template<> constexpr char max_value<char>() { return CHAR_MAX; }
//...

template<typename Iter>
Iter my_algo(Iter p)
{
    auto x = max_value<Value_type<Iter>>();  // dziaa dla typw majcych wyspecjalizowan funkcj max_value()
    //...
}
---------------
int max2(int) { return INT_MAX; }
char max2(char) { return CHAR_MAX; }

template<typename Iter>
Iter my_algo2(Iter p)
{
    auto x = max2(Value_type<Iter>{});  // dziaa dla typw, dla ktrych przeciono max2()
    //...
}