日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > 單片機 > 程序喵大人


type_traits在C++中是非常有用的技巧,可以說如果不懂type_traits,那根本看不懂stl相關(guān)代碼,最近對type_traits比較感興趣,于是找到了gcc的type_traits源碼通讀了一遍,總結(jié)一下。

type_traits稱為類型萃取技術(shù),主要用于編譯期獲取某一參數(shù)、某一變量、某一個類等等任何C++相關(guān)對象的類型,以及判斷他們是否是某個類型,兩個變量是否是同一類型,是否是標(biāo)量、是否是引用、是否是指針、是左值還是右值,還可以將某個為某個類型去掉cv(const volitale)屬性或者增加cv屬性等等。


SFINAE

SFINAE技術(shù),Substitution Failure is Not An Error,在編譯期編譯時,會將函數(shù)模板的形參替換為實參,如果替換失敗編譯器不會當(dāng)作是個錯誤,直到找到那個最合適的特化版本,如果所有的模板版本都替換失敗那編譯器就會報錯,以std::enable_if舉個例子。

#include
#include

using std::cout;
using std::endl;

template
auto func(T t) -> std::enable_if_t::value, int>
{
 cout << "int" << endl;
}

template
auto func(T t) -> std::enable_if_t::value, double>
{
 cout << "double" << endl;
}

int main()
{
 int a = 1;
 double b = 2.9;
 func(a);
 func(b);

 // float c = 34.5;
 // func(c);

 return 0;
}

編譯運行:g++ test.cc -std=c++14; ./a.out
int
double

注釋部分的代碼如果打開就會編譯失敗,代碼中明確規(guī)定了func函數(shù)只接收類型為int和double的參數(shù),向func中傳入其它類型參數(shù)編譯器則會報錯。

通過SFINAE技術(shù)可以完成很多有趣的事,比如根據(jù)參數(shù)類型做不同的定制化操作。


type_traits原理

type_traits最核心的結(jié)構(gòu)體應(yīng)該就是integral_constant,它的源代碼如下:

template
 struct integral_constant
 {
 static constexpr _Tp                  value = __v;
 typedef _Tp                           value_type;
 typedef integral_constant<_Tp, __v>   type;
 constexpr operator value_type() const noexcept { return value; }
 constexpr value_type operator()() const noexcept { return value; }
 };

 typedef integral_constant     true_type;
 typedef integral_constant    false_type;

基本上type_traits的每個功能都會使用到true_type和false_type,后續(xù)會介紹,這里先介紹代碼中那兩個operator函數(shù)的具體含義,operator type() const用于類型轉(zhuǎn)換,而type operator()() const用于仿函數(shù),見代碼。

#include
#include

using std::cout;
using std::endl;

class Test
{
public:
 operator int() const
 {
 cout << "operator type const " << endl;
 return 1;
 }

 int operator()() const
 {
 cout << "operator()()" << endl;
 return 2;
 }
};

int main()
{
 Test t;
 int x(t);
 int xx = t;
 t();
 return 0;
}

編譯運行:g++ test.cc; ./a.out
operator type const
operator type const
operator()()

還有個主要的模板是conditional

template
 struct conditional;

 template
 struct conditional
 { typedef _Iftrue type; };

 // Partial specialization for false.
 template
 struct conditional
 { typedef _Iffalse type; };

當(dāng)模板的第一個參數(shù)為true時type就是第二個參數(shù)的類型,當(dāng)?shù)谝粋€參數(shù)為false時type就是第三個參數(shù)的類型,通過conditional可以構(gòu)造出or and等功能,類似我們平時使用的帶短路功能的|| &&,具體實現(xiàn)如下:

template
 struct conditional;

 template
 struct __or_;

 template<>
 struct __or_<>
 : public false_type
 { };

 template
 struct __or_
 : public _B1
 { };

 template
 struct __or_<_B1, _B2>
 : public conditional<_B1::value, _B1, _B2>::type
 { };

 template
 struct __or_<_B1, _B2, _B3, _Bn...>
 : public conditional<_B1::value, _B1, __or_<_B2, _B3, _Bn...>>::type
 { };

 template
 struct disjunction
 : __or_<_Bn...>
 { };

通過disjunction可以實現(xiàn)析取功能,type為B1, B2, B…中第一個value為true的類型。

// cpp reference中的示例代碼
struct Foo {
 template
 struct sfinae_unfriendly_check {
 static_assert(!std::is_same_v);
 };

 template
 Foo(T, sfinae_unfriendly_check= {});
};

template 
struct first_constructible {
 template 
 struct is_constructible_x : std::is_constructible {
 using type = T;
 };
 struct fallback {
 static constexpr bool value = true;
 using type = void;  // type to return if nothing is found
 };

 template 
 using with = typename std::disjunction..., fallback>::type;
};

// OK, is_constructible not instantiated
static_assert(std::is_same_v::with, int>);

static_assert(std::is_same_v::with<>, std::string>);
static_assert(std::is_same_v::with, std::string>);
static_assert(std::is_same_v::with, void>);

再看看conjunction的實現(xiàn)

template
 struct __and_;

 template<>
 struct __and_<>
 : public true_type
 { };

 template
 struct __and_
 : public _B1
 { };

 template
 struct __and_<_B1, _B2>
 : public conditional<_B1::value, _B2, _B1>::type
 { };

 template
 struct __and_<_B1, _B2, _B3, _Bn...>
 : public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type
 { };

 template
 struct conjunction
 : __and_<_Bn...>
 { };

通過conjunction可以判斷函數(shù)的參數(shù)類型是否相同,代碼如下:

#include
#include

// func is enabled if all Ts... have the same type as T
template 
std::enable_if_t...>> func(T, Ts...) {
 std::cout << "all types in pack are T\n";
}

// otherwise
template 
std::enable_if_t...>> func(T, Ts...) {
 std::cout << "not all types in pack are T\n";
}

int main() {
 func(1, 2, 3);
 func(1, 2, "hello!");
}

輸出:
all types in pack are T
not all types in pack are T

再舉一些平時用的很多的例子,還可以判斷某個類型是否有const屬性,添加去除某個類型的左值引用或者右值引用,添加去除某個類型的const或者volatile。

#include
#include

int main()
{
 std::cout << std::boolalpha;
 std::cout << std::is_const::value << '\n'; // false
 std::cout << std::is_const::value  << '\n'; // true
 std::cout << std::is_const::value  << '\n'; // false
 std::cout << std::is_const::value  << '\n'; // true
 std::cout << std::is_const::value  << '\n'; // false
}

is_const實現(xiàn)很簡單,就是利用模板匹配特性,其它的is_volatile等類似

template
 struct is_const
 : public false_type { };

 template
 struct is_const
 : public true_type { };

is_same的實現(xiàn)如下:

template
 struct is_same
 : public false_type { };

 template
 struct is_same<_Tp, _Tp>
 : public true_type { };

包括移除引用的功能, remove_reference

/// remove_reference
 template
 struct remove_reference
 { typedef _Tp   type; };

 template
 struct remove_reference<_Tp&>
 { typedef _Tp   type; };

 template
 struct remove_reference<_Tp&&>
 { typedef _Tp   type; };

 // C++14之后這種xxx_t=xxx::type
 template
 using remove_reference_t = typename remove_reference::type;

add_const, add_volatile, add_cv等的實現(xiàn)

template
 struct add_const
 { typedef _Tp const     type; };

 /// add_volatile
 template
 struct add_volatile
 { typedef _Tp volatile     type; };

 /// add_cv
 template
 struct add_cv
 {
 typedef typename
 add_const::type     type;
 };
本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉