type_traits类型选择功能,在一定的程度上,消除了if..else,switch-case。提供类型判断的功能。
c++11定义常量:
template
struct GetLeftSize::std::interal_constant
{};
根据GetLeftSize::value来获取常量1;
类型判断的traits:
is_void
is_class
..........
is_const;
std::cout<<"int::"< 3.判断两个类型是否相同 is_baseof:判断两种类型是否为继承关系 is_convertible:判断前面的模版参数类型能否转换为后面的模版参数类型 4.类型转换的traits struct remove_const;移除const struct add_const;添加const struct remove_reference移除引用 带有cv template T* Create() { retrun new T(); } int *P=Create template typename std::remove_cv { typedef typename std::remove_cv return new U(); } std::decay是先移除引用,在移除cv符。 std::decay对于函数来说,是添加指针,可以将函数变为函数指针类型,然后保存起来。 template struct SimpleFunction{ using FnType=typename std::decacy SimpleFunction(F& f):m_fn(f); void Run(){ m_fn(); } template struct conditional; 在std::conditional的模版参数,如果B为true,这conditional::type为T,否则为F。 tempalte class result_of 用来在编译期获取一个可调用的对象。 std::enable_if,是的函数在判断条件B为true的情况下f才有有效。 template typename std::enable_if return t; optional 作用:解决函数返回无效值的问题,如果查找不到对象,返回一个无效值,表明指向失败,返回一个未初始化的optional对象。 1.要内存对齐,调用place_new创建内存块,需要内存对齐,提高效率 2.多个参数有右值引用,和完美转发。 #pragma once template } 惰性求值,一般用于函数式的编程,表达式不在它被绑定到的变量后就立即求值,而是在后面的某个时候求值。 典型的应用场景是:当初始化某个对象的时,该对象创建需要较长的时间,同时也需要托管堆上分配较多的空间,初始化的时候变得很慢。 #pragma once template 遇到的错误:记得如果定义了右值引用,一定要传递右值,否则,会造成异常。如果lazy方法,如果传递的时function<>,会造成求值的时候,找不到f。 dll中,要定义一个对应的函数指针,接着调用GetProcAddress获取函数指针,最后调用该函数。 思路: 1.定义一个通用的指向函数,通过传递函数的名称和参数来调用 Ret CallDllFunc(const string& funcName, T arg); 2.通过函数名称,来获取一个范型的std::function来调用 解决两个问题: 1.函数的返回类型是多样的 2.函数的参数的类型和个数是多样的。 template std::function auto it =m_map.find(funcName); if(it==m_map.end()) auto addr=GetProcAddrss(m_hmod,funcName.c_str()); if(!addr) return nullptr; m_map.insert(std::make_pair(funcName,addr)); return std::function } template typename std::result_oof auto f=GetFunction return f(std::forward 它的原理是函数的指向结果,是一个的参数。 m_fn表示的上一个函数。 template class Task; template class Task { Task(std::function R run(Args&& ... args){ return m_fn(std::forward(args)...); } template auto Then(F&& f)->task using return_type=typename std::result_of(F(R))::type; auto func=std::move(m_fn); return Task return f(func(std::forward }); } private: std::function(R(Args..)) m_fn; } 任何类型的值都可以赋值给它,进行类型擦除。Any可以容纳所有的数据类型,通过继承来擦除类型,基类不含模版参数,派生类才有模版参数,模版参数正式赋值的类型。 赋值: 把派生类的对象赋值给基类指针,基类只是原有数据的一个占位符,多态的隐士转换擦除了原始数据类型。 取值: 向下转换成派生类型来获取原始数据。 #pragma once template bool isNull() const { template struct Base { 1.找出最大的typesize用来分配内存对齐的缓冲区 template struct IntegerMax: std::interal_constant IntergerMax 对齐大小: template struct MaxAlign:std::intergral_constant 2.类型检查和缓冲区中创建对象 template struct Contains : std::true_type{}; template struct Contains :std::conditional< std::is_same Contains 通过bool值,contains 3.缓冲区上创建对象 new(data) T(value) 其主要的作用是获取所有的函数语义的函数类型,返回类型,参数个数和参数的具体类型。 如: int func(int a,string b); function_traits function_traits function_traits function_traits 实现function_traits关键是通过模版特化和可变参数模版来获取函数的类型和返回类型。 template struct function_traits; 在通过特化,将返回类型和可变参数作为模版参数,可以获取函数的类型,返回值和参数的个数。 #pragma once template template using stl_function_type = std::function typedef Ret(*pointer)(Args...); template }; }; #define FUNCTION_TRAITS(...)\ FUNCTION_TRAITS() template template template template 根据条件选择的traits
获取可调用对象的返回类型traits
根据某些条件禁用或者启用某些类型的traits
Optional的实现
#include
class MyOptional {
using data_t = typename std::aligned_storage
public:
MyOptional() {
MyOptional(const T& v) {
Create(v);
}
MyOptional(const MyOptional& other) {
if (other.IsInit())
Assign(other);
}
template
void Emplace(Args&&... args) {
Destory();
Create(std::forward
}
bool IsInit() const {
return m_hasInit;
}
explicit operator bool() const {
return IsInit();
}
T const& operator*() const {
if (IsInit()) {
return *((T*)(&m_data));
}
throw std::logic_error("is not init");
}
private:
template
void Create(Args... args) {
new (&m_data) T(std::forward
m_hasInit = true;
}
void Destory() {
if (m_hasInit)
{
m_hasInit = false;
((T*)&m_data)->~T();
}
}
void Assign(const MyOptional& other) {
if (other.IsInit()) {
Copy(other.m_data);
m_hasInit = true;
}
else {
Destory();
}
}
void Copy(const data_t& val) {
Destory();
new (&m_data) T(*(T*)&val);
}
private:
bool m_hasInit = false;
data_t m_data;
};惰性求值
#include"optional.h"
#include
#include
template
struct Lazy {
Lazy(){}
Lazy(Func&& f, Args && ... args) {
m_func = [&f, &args...] {
return f(args...);
};
}
T const & Value() {
if (!m_value.IsInit()) {
m_value = m_func();
}
return *m_value;
}
bool IsValueCreated() const {
return m_value.IsInit();
}
private:
std::function
MyOptional
};
template
Lazy
return Lazy
}
dll帮助类
lamada链式调用
Any类的实现
#include
#include
struct Any {
Any(void) :m_tpIndex(std::type_index(typeid(void))){}
Any(Any& that):m_ptr(that.Clone()),m_tpIndex(that.m_tpIndex){}
Any(Any&& that):m_ptr(std::move(that.m_ptr)),m_tpIndex(that.m_tpIndex){}
Any(U&& value) : m_ptr(new Derived
m_tpIndex(std::type_index(typeid(typename std::decay::type))) {}
return !bool(m_ptr);
}
template
return m_tpIndex == std::type_index(typeid(U));
}
U& AnyCast(){
if (!Is()) {
std::cout << "can not cast" << typeid(U).name() << "to " << m_tpIndex.name() << std::endl;
throw std::bad_cast();
}
auto derived = dynamic_cast
return derived->m_value;
}
Any& operator=(const Any& a) {
if (m_ptr == a.m_ptr)
return *this;
m_ptr = a.Clone();
m_tpIndex = a.m_tpIndex;
return *this;
}
private:
struct Base;
typedef std::unique_ptr
virtual ~Base(){}
virtual BasePtr Clone() const=0;
};
template
struct Derived :Base {
template
Derived(U && value) :m_value(std::forward(value)){}
BasePtr Clone() const {
return BasePtr(new Derived
}
T m_value;
};
BasePtr Clone() const
{
if (m_ptr != nullptr) {
return m_ptr->Clone();
}
return nullptr;
}
BasePtr m_ptr;
std::type_index m_tpIndex;
};Variant的实现
function_traits
实现function_tratis的关键技术
#include
#include
struct function_traits;
struct function_traits
{
public:
enum {arity=sizeof...(Args) };
typedef Ret function_type(Args...);
typedef Ret return_type;
struct args {
static_assert(I < arity, "index is out of range");
using type = typename std::tuple_element < I, std::tuple
};
};
template
struct function_traits
{
template
struct function_traits
{
template
struct function_traits
/*
FUNCTION_TRAITS(const)
FUNCTION_TRAITS(volatile)
FUNCTION_TRAITS(const volatile)*/
struct function_traits :function_traits
typename function_traits
return static_cast
}
typename function_traits
return static_cast
}
typename function_traits
return static_cast
}