Here is an example which will not compile, because of the static_assert fails:// Illustrates a static_assert on top of the template specialization stuff.
// Compiles, meaning that the static assert holds (in this program at least).
#include <iostream>
#include <string>
#include <type_traits>
template <typename S, typename T> class A{ // The primary template class
public:
int a;
S s;
T t;
A() : a{1}, s{}, t{} {};
};
template<> class A <int, std::string> { // Complete specialization to S = int, T = string
public:
int a;
int s;
std::string t;
A() : a{2}, s{}, t{}{};
};
template<typename S, typename T> class A <S*, T*> { // Partial Specialization to pointers
public:
int a;
S s;
T t;
A() : a{3}, s{}, t{}{};
static_assert(!std::is_pointer<S>::value, "S is not (normally) expected to be a pointer type");
};
template<typename T> class A <T, T> { // Partial specialization: T and S are the same types
public:
int a;
T s;
T t;
A() : a{4}, s{}, t{}{};
};
int main(){
A<double,bool> a1; // Use of A<S,T>
A<int,std::string> a2; // Use of A<int,string>
A<double*,std::string*> a3; // Use of A<T*,S*>
A<double**,std::string*> a3_1; // Use of A<T*,S*> - causes the static_assert to fail.
A<double**,std::string**> a3_2; // Use of A<T*,S*> - causes the static_assert to fail.
A<double,double> a4; // Use of A<T,T>
std::cout << a1.a << std::endl; // 1
std::cout << a2.a << std::endl; // 2
std::cout << a3.a << std::endl; // 3
std::cout << a4.a << std::endl; // 4
}