日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++11-type_traits类型萃取

發布時間:2024/4/17 c/c++ 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++11-type_traits类型萃取 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Type_traits

type_traits類型選擇功能,在一定的程度上,消除了if..else,switch-case。提供類型判斷的功能。

c++11定義常量:

template<typename Type>

struct GetLeftSize::std::interal_constant<int,1>

{};

根據GetLeftSize::value來獲取常量1;

類型判斷的traits:

is_void

is_class

..........

is_const;

std::cout<<"int::"<<std::is_const<int>::value<<endl;

3.判斷兩個類型是否相同

is_baseof:判斷兩種類型是否為繼承關系

is_convertible:判斷前面的模版參數類型能否轉換為后面的模版參數類型

4.類型轉換的traits

struct remove_const;移除const

struct add_const;添加const

struct remove_reference移除引用

?

帶有cv

template<typename T>

T* Create()

{

? ? retrun new T();

}

int *P=Create<cosnt volatile int&>();----------》無法通過編譯

template<typename T>

typename std::remove_cv<typename std::remove_refrence<T>::type>::type* Create()

{

? typedef typename std::remove_cv<typename std::remove_reference<T>::type>::type U;

? return new U();

}

std::decay是先移除引用,在移除cv符。

std::decay對于函數來說,是添加指針,可以將函數變為函數指針類型,然后保存起來。

template<typename F>

struct SimpleFunction{

using FnType=typename std::decacy<F>::type;

SimpleFunction(F& f):m_fn(f);

void Run(){

m_fn();

}

根據條件選擇的traits

template<bool B, class T, class F>

struct conditional;

在std::conditional的模版參數,如果B為true,這conditional::type為T,否則為F。

獲取可調用對象的返回類型traits

tempalte<class F, class ...ArgTypes>

class result_of<F(ArgTypes....)>

用來在編譯期獲取一個可調用的對象。

根據某些條件禁用或者啟用某些類型的traits

std::enable_if,是的函數在判斷條件B為true的情況下f才有有效。

template<class T>

typename std::enable_if<std::is_arithemtic<T>::value,T>::type foo(T t)

? ?return t;

Optional的實現

optional<T> 對optional初始化之后,這個optional有效的,否則無效的。

作用:解決函數返回無效值的問題,如果查找不到對象,返回一個無效值,表明指向失敗,返回一個未初始化的optional對象。

1.要內存對齊,調用place_new創建內存塊,需要內存對齊,提高效率

2.多個參數有右值引用,和完美轉發。

#pragma once
#include<type_traits>

template<typename T>
class MyOptional {
?? ?using data_t = typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type;
public:
?? ?MyOptional() {

?? ?}
?? ?MyOptional(const T& v) {
?? ??? ?Create(v);
?? ?}
?? ?MyOptional(const MyOptional& other) {
?? ??? ?if (other.IsInit())
?? ??? ??? ?Assign(other);
?? ?}
?? ?template<class... Args>
?? ?void Emplace(Args&&... args) {
?? ??? ?Destory();
?? ??? ?Create(std::forward<Args>(args)...);
?? ?}
?? ?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<class... Args>
?? ?void Create(Args... args) {
?? ??? ?new (&m_data) T(std::forward<Args>(args)...);
?? ??? ?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;
};

惰性求值

惰性求值,一般用于函數式的編程,表達式不在它被綁定到的變量后就立即求值,而是在后面的某個時候求值。

典型的應用場景是:當初始化某個對象的時,該對象創建需要較長的時間,同時也需要托管堆上分配較多的空間,初始化的時候變得很慢。

#pragma once
#include"optional.h"
#include<functional>
#include<memory>
template<typename T>
struct Lazy {
?? ?Lazy(){}

?? ?template<typename Func, typename... Args>
?? ?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<T()> m_func;
?? ?MyOptional<T> m_value;
};
template<class Func, typename... Args>
Lazy<typename std::result_of<Func(Args...)>::type> lazy(Func &&func, Args&& ... args) {
?? ?return Lazy<typename std::result_of<Func(Args...)>::type>(std::forward<Func>(func), std::forward<Args>(args)...);
}
?

遇到的錯誤:記得如果定義了右值引用,一定要傳遞右值,否則,會造成異常。如果lazy方法,如果傳遞的時function<>,會造成求值的時候,找不到f。

?

dll幫助類

dll中,要定義一個對應的函數指針,接著調用GetProcAddress獲取函數指針,最后調用該函數。

思路:

1.定義一個通用的指向函數,通過傳遞函數的名稱和參數來調用

Ret CallDllFunc(const string& funcName, T arg);

2.通過函數名稱,來獲取一個范型的std::function來調用

解決兩個問題:

1.函數的返回類型是多樣的

2.函數的參數的類型和個數是多樣的。

template<typename T>

std::function<T> GetFunction(const string& funcName){

? ?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<T>((T*)(it->second));

}

?

template<typename T, typename... Args>

typename std::result_oof<std::function<T>(Args...)::type ExcuteFunc(const string& name, Args&& ... args)

?auto f=GetFunction<T>(funcName);

return f(std::forward<Args(args));

?

lamada鏈式調用

它的原理是函數的指向結果,是一個的參數。

m_fn表示的上一個函數。

template<typename T>

class Task;

template<typename R, typename ... Args>

class Task<R(Args...)>

{

? ?Task(std::function<R(Args..)> && f):m_fn(f){}

? R run(Args&& ... args){

? ? ? ? ? ? ?return m_fn(std::forward(args)...);

}

template<typename F>

auto Then(F&& f)->task<std::result_of(F(R))::type(args){

using return_type=typename std::result_of(F(R))::type;

auto func=std::move(m_fn);

return Task<return_type(Args...)>([func, f](Args&& ... args){

? ? return f(func(std::forward<Args>(args)...));

});

}

private:

? ? ? std::function(R(Args..)) m_fn;

}

?

Any類的實現

任何類型的值都可以賦值給它,進行類型擦除。Any可以容納所有的數據類型,通過繼承來擦除類型,基類不含模版參數,派生類才有模版參數,模版參數正式賦值的類型。

賦值:

把派生類的對象賦值給基類指針,基類只是原有數據的一個占位符,多態的隱士轉換擦除了原始數據類型。

取值:

向下轉換成派生類型來獲取原始數據。

#pragma once
#include<memory>
#include<typeindex>
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){}

?? ?template<typename U, class = typename
?? ??? ?std::enable_if<!std::is_same<typename std::decay<U>::type, Any>::value, U>::type>?
?? ??? ?Any(U&& value) : m_ptr(new Derived<typename std::decay<U>::type>(std::forward<U>(value))),
?? ??? ??? ?m_tpIndex(std::type_index(typeid(typename std::decay<U>::type))) {}

?? ?bool isNull() const {
?? ??? ?return !bool(m_ptr);
?? ?}
?? ?template<class U> bool Is() const {
?? ??? ?return m_tpIndex == std::type_index(typeid(U));
?? ?}

?? ?template<class U>
?? ?U& AnyCast(){
?? ??? ?if (!Is<U>()) {
?? ??? ??? ?std::cout << "can not cast" << typeid(U).name() << "to " << m_tpIndex.name() << std::endl;
?? ??? ??? ?throw std::bad_cast();
?? ??? ?}
?? ??? ?auto derived = dynamic_cast<Derived<U>*> (m_ptr.get());
?? ??? ?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<Base> BasePtr;

?? ?struct Base {
?? ??? ?virtual ~Base(){}
?? ??? ?virtual BasePtr Clone() const=0;
?? ?};
?? ?template<typename T>
?? ?struct Derived :Base {
?? ??? ?template<typename U>
?? ??? ?Derived(U && value) :m_value(std::forward<U>(value)){}
?? ??? ?BasePtr Clone() const {
?? ??? ??? ?return BasePtr(new Derived<T>(m_value));
?? ??? ?}
?? ??? ?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的實現

1.找出最大的typesize用來分配內存對齊的緩沖區

template<typename T, tyepname ... Args>

struct IntegerMax: std::interal_constant<int, (sizeof(T)>IntergerMax(Args...>::value?sizeof(T):IntegerMax<Args...>::value)>();

IntergerMax<Types....>::value;

對齊大小:

template<typename...Args>

struct MaxAlign:std::intergral_constant<int, IntegerMax<std::alignment_of<Args>::value...>::value>{}

2.類型檢查和緩沖區中創建對象

template<typename T, typename... List>

struct Contains : std::true_type{};

?

template <typename T, typename Head, typename... Rest>

struct Contains<T, Head, Rest...>

:std::conditional< std::is_same<T, Head>::value, std::true_type,

Contains<T, Rest...>>::type();

通過bool值,contains<T,Types>::value可以判斷是否包含某種類型。

3.緩沖區上創建對象

new(data) T(value)

?

function_traits

其主要的作用是獲取所有的函數語義的函數類型,返回類型,參數個數和參數的具體類型。

如:

int func(int a,string?b);

function_traits<decltype(func)>::function_type;//int _cdecl(int,string);

function_traits<decltype(func)>::return_type;//int

function_traits<decltype(func)>::arity;//2

function_traits<decltype(func)>::arg_type<0>; //獲取第一個參數的類型,int

實現function_tratis的關鍵技術

實現function_traits關鍵是通過模版特化和可變參數模版來獲取函數的類型和返回類型。

template<typename T>

struct function_traits;

在通過特化,將返回類型和可變參數作為模版參數,可以獲取函數的類型,返回值和參數的個數。

#pragma once
#include<functional>
#include<tuple>

template<typename T>
struct function_traits;

template<typename Ret,typename... Args>
struct function_traits<Ret(Args...)>
{
public:
?? ?enum {arity=sizeof...(Args) };
?? ?typedef Ret function_type(Args...);
?? ?typedef Ret return_type;

?? ?using stl_function_type = std::function<function_type>;

?? ?typedef Ret(*pointer)(Args...);

?? ?template<size_t I>
?? ?struct args {
?? ??? ?static_assert(I < arity, "index is out of range");
?? ??? ?using type = typename std::tuple_element < I, std::tuple<Args...>>::type;
?? ?};
};
template<typename Ret, typename... Args>
struct function_traits<Ret(*)(Args...)>:function_traits<Ret(Args...)>
{

};
template<typename Ret, typename... Args>
struct function_traits<std::function<Ret(Args...)>> :function_traits<Ret(Args...)>
{

};

#define FUNCTION_TRAITS(...)\
template<typename ReturnType, typename ClassType, typename ... Args>\
struct function_traits<ReturnType(ClassType::*)(Args...)>:function_traits<ReturnType(Args...)>{ };\

FUNCTION_TRAITS()
/*
FUNCTION_TRAITS(const)
FUNCTION_TRAITS(volatile)
FUNCTION_TRAITS(const volatile)*/

template<typename Callable>
struct function_traits :function_traits<decltype(&Callable::operator())> {};

template<typename Function>
typename function_traits<Function>::stl_function_type to_function(const Function & lambda) {
?? ?return static_cast<typename function_traits<Function>::stl_function_type>(lambda);
}

template<typename Function>
typename function_traits<Function>::stl_function_type to_function(const Function && lambda) {
?? ?return static_cast<typename function_traits<Function>::stl_function_type>(std::forward<Function>(lambda));
}

template<typename Function>
typename function_traits<Function>::pointer to_function(const Function & lambda) {
?? ?return static_cast<typename function_traits<Function>::pointer>((lambda));
}


?

?

總結

以上是生活随笔為你收集整理的c++11-type_traits类型萃取的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。