原则:所有偏特化的时候,template的<>中写的typename在class中必须全部使用,所有class中使用的typename,必须在class<>和template<>中写明!!!!!!!
偏特化主要分两种类型
eg: template
模板特化(template specialization)不同于模板的实例化,模板参数在某种特定类型下的具体实现称为模板特化。模板特化有时也称之为模板的具体化,分别有函数模板特化和类模板特化。
#include
using namespace std;
template<typename T>class A
{
T num;
public:
A()
{
num=T(6.6);
}
void print()
{
cout<<"A'num:"<<num<<endl;
}
};
template<> class A<char*>
{
char* str;
public:
A(){
str="A' special definition ";
}
void print(){
cout<<str<<endl;
}
};
int main()
{
A<int> a1; //显示模板实参的隐式实例化
a1.print();
A<char*> a2; //使用特化的类模板
A2.print();
}
模板偏特化(Template Partitial Specialization)是模板特化的一种特殊情况,指显示指定部分模板参数而非全部模板参数,或者指定模板参数的部分特性分而非全部特性,也称为模板部分特化。与模板偏特化相对的是模板全特化,指对所有的模板参数进行特化。模板全特化与模板偏特化共同组成模板特化。
模板偏特化主要分为两种,一种是指对部分模板参数进行全特化,另一种是对模板参数特性进行特化,包括将模板参数特化为指针、引用或是另外一个模板类。
template <class _Tp, class _Up> struct _LIBCPP_TEMPLATE_VIS is_same : public false_type {
};
template <class _Tp> struct _LIBCPP_TEMPLATE_VIS is_same<_Tp, _Tp> : public true_type {
};
is_same函数手动实现,利用偏特化原理
#include
#include
template<typename type, type t>
class Type
{
public:
static constexpr type value = t;
};
class true_type: public Type<bool , true>{
};
class false_type: public Type<bool , false>{
};
template<typename type1, typename type2>
class is_same: public false_type
{
};
template<typename type1> //模板偏特化
class is_same <type1, type1>: public true_type
{
};
int main()
{
std::cout<<std::is_same<int,int>::value<<std::endl;
std::cout<<is_same<int,int>::value<<std::endl;
return 0;
}
//
// main.cpp
// ticketmachine
//
// Created by Python_liu on 2019/8/6.
// Copyright © 2019 liuxz. All rights reserved.
//
#include "TicketMachine.hpp"
#include
#include
using namespace std;
class type_a
{
public:
void fun1()
{
cout<<"world! "<<endl;
}
};
template<typename T>
class test2
{
public:
void fun2()const
{
cout<<"wow"<<endl;
}
T t;
};
template<typename T>
class test1
{
public:
T* operator->();
using _test2 = test2<int>;//等价于 typedef test2 _test2!!!
private:
T a;
};
template<typename T>
T* test1<T>::operator->()
{
return &a;
}
template<typename T,class D>//未特化!
class test3
{
public:
void fun3(T num1,D num2)const
{
cout<<"standard class template"<<endl;
}
};
template<class D>//偏特化!
class test3<int,D>
{
public:
void fun3(int num1,D num2)
{
cout<<"partial class template"<<endl;
}
};
template<typename T,class D>//偏特化!
class test3<T*,D*>
{
public:
void fun3(const T* num1, const D* num2)
{
cout<<"new partial class template"<<endl;
}
};
template<>//全特化!
class test3<int,int*>
{
public:
void fun3(const int num1, const int* num2)
{
cout<<"new partial class template"<<endl;
}
};
int main(int argc, const char * argv[]) {
// insert code here...
cout<<"hello"<<endl;
test1<type_a> h;
h->fun1();
test1<type_a>::_test2 k;
k.fun2();
typedef int i[5];
i ii;
cout<<sizeof(ii)<<endl;
test3<int,int> b;
b.fun3(30, 30);//偏特化的优先级高于普通模板!!!!!!
test3<char,char> c;
c.fun3('a', 'b');//标准模板的优先级最低!!!
test3<char*, char*> d;
d.fun3("haha", "hehe");//全特化的优先级最高!!!
return 0;
}
模板的特化与偏特化需要注意一下几点:
1、模板是有优先级的,优先级高低是,全特化>偏特化>普通模板
2、偏特化时,template class
3、偏特化时,template
顺序应该是,先把泛化的模板的默认参数补上,然后从上到下进行比较,谁的优先级高就走谁
#include
#include
#include
using namespace std;
struct GenerateValue
{
using Generated_tag = int;
};
struct GenerateValue1
{
using Generated_tag = int;
};
template<typename T, typename Tagged = void>
struct has_generated_tag {
static const bool value = true;
has_generated_tag(){
cout<<"1111"<<endl;};
};
template<typename T>
struct has_generated_tag<T, typename T::Generated_tag> {
static const bool value = false; // used it type defines an internal type called Generated_tag
has_generated_tag(){
cout<<"2222"<<endl;};
};
// C++17-style simplification of syntax.
template<class T>
bool is_generated_type_v = has_generated_tag<T>::value;
int main()
{
cout << "is_generated_type_v: " << is_generated_type_v<GenerateValue> << endl;
cout << "is_generated_type_v: " << is_generated_type_v<GenerateValue1> << endl;
cout << "is_generated_type_v: " << is_generated_type_v<string> << endl;
system("pause");
}
#include
using namespace std;
template <typename MethodTraits, typename Signature = typename MethodTraits::Signature>
class Method_impl {
public:
Method_impl() {
cout << "general" <<endl; }
};
template <typename MethodTraits,typename R, typename... Args>
class Method_impl<MethodTraits,R(Args...)> {
public:
Method_impl() {
cout << "R(Args)" <<endl; }
};
template <typename MethodTraits, typename R>
class Method_impl<MethodTraits, R()> {
public:
Method_impl() {
cout << "R()" << endl; }
};
template <typename MethodTraits,typename... Args>
class Method_impl<MethodTraits,void(Args...)>{
public:
Method_impl() {
cout << "void(args)" << endl; }
void operator()(Args... args) const {
cout << "()" << endl; }
void fun1(Args... args) const {
cout << "[]" << endl; }
};
template <typename MethodTraits>
class Method_impl<MethodTraits, void()>
{
public:
Method_impl() {
cout << "void()" << endl; }
};
template<typename MethodTraits, typename Signature = typename MethodTraits::Signature>
class Method;
template<typename MethodTraits, typename R , typename... Args>
class Method<MethodTraits, R(Args...)> {
private:
using impl = Method_impl<MethodTraits>;
public:
Method() :m_impl() {
};
void operator()(Args... args) const {
m_impl(args...); }
void fun(Args... args) const {
m_impl.fun1(args...); }
private:
impl m_impl;
};
struct set_get_value
{
static constexpr int Id{
1 };
using Output = double;
using Signature = Output(int);
};
template<typename... Args>
struct set_value
{
static constexpr int Id{
2 };
using Output = void;
using Signature = Output(Args...);
};
struct other
{
static constexpr int Id{
2 };
using Output = void;
using Signature = void;
};
void testmethod()
{
Method_impl<set_get_value> method1; //R(args)
Method_impl<set_get_value, int()> method2; //R()
Method_impl<set_get_value, int(void)> method3; //R()
Method_impl<set_get_value, int(int, double)> method8; //general
Method_impl<set_get_value, void> method4; //general
Method_impl<set_get_value, void()> method5; //void()
Method_impl<set_get_value, void(void)> method6; //void()
Method_impl<set_get_value, void(int)> method7; //void(args)}
}
void testOperator() {
Method<set_value<int,int>> methods;
int value = 56;
methods(value,50);
methods.fun(value,50);
}
template<typename Signature, typename Deserializer>
int deserialize_args(Deserializer& deserializer)
{
cout << "des"<<deserializer << endl;
return 0;
}
void testDeserialization()
{
double deserializer = 3.14;
auto args = deserialize_args<int()>(deserializer);
}
int main()
{
testOperator();
system("pause");
return 0;
}