百度apollo源碼學(xué)習(xí)(一)DEFINE-創(chuàng)新互聯(lián)

文章目錄
  • 前言
  • 源碼
    • 解讀
    • SFINAE機(jī)制
    • 舉例
  • 參考

創(chuàng)新互聯(lián)是一家集成都做網(wǎng)站、成都網(wǎng)站制作、網(wǎng)站頁面設(shè)計(jì)、網(wǎng)站優(yōu)化SEO優(yōu)化為一體的專業(yè)網(wǎng)站設(shè)計(jì)公司,已為成都等多地近百家企業(yè)提供網(wǎng)站建設(shè)服務(wù)。追求良好的瀏覽體驗(yàn),以探求精品塑造與理念升華,設(shè)計(jì)最適合用戶的網(wǎng)站頁面。 合作只是第一步,服務(wù)才是根本,我們始終堅(jiān)持講誠信,負(fù)責(zé)任的原則,為您進(jìn)行細(xì)心、貼心、認(rèn)真的服務(wù),與眾多客戶在蓬勃發(fā)展的市場環(huán)境中,互促共生。
前言

最近學(xué)習(xí)百度apollo源碼,發(fā)現(xiàn)很多看不懂的代碼,因才疏學(xué)淺,只能通過上網(wǎng)搜索,逐步理解,然后將理解完成的內(nèi)容再次進(jìn)行記錄,其中參考了很多其他博主的博客。
我覺得對于程序員來說,看優(yōu)秀的代碼是進(jìn)步最快的方式,看代碼不僅要看懂代碼,還要看明白設(shè)計(jì)者設(shè)計(jì)該部分代碼的框架。
廢話不多少,接下來看一下apollo中基于C++類型萃取實(shí)現(xiàn)的結(jié)構(gòu)體成員變量或函數(shù)的存在性判斷的宏定義:DEFINE_TYPE_TRAIT該宏定義位于:cyber/base/macros.h中。

源碼
#define DEFINE_TYPE_TRAIT(name, func)                     \
  template   \
  struct name {   \
	// 僅當(dāng)T是一個(gè)類類型時(shí),“Class::func”才是存在的,從而這個(gè)泛型函數(shù)的實(shí)例化才是可行的
	// 否則,就將觸發(fā)SFINAE
    template \
    static constexpr bool Test(decltype(&Class::func)*) {\
      return true;                                        \
    }                                                     \
    // 僅當(dāng)觸發(fā)SFINAE時(shí),編譯器才會(huì)“被迫”選擇這個(gè)版本
    template   \
    static constexpr bool Test(...) { \
      return false;                                       \
    }                                                     \
                                                          \
    static constexpr bool value = Test(nullptr);       \
  };                                                      \
                                                          \
  template   \
  constexpr bool name::value;
解讀

這個(gè)宏定義創(chuàng)建了一個(gè)struct name的結(jié)構(gòu)體constexpr bool name::value的變量。
第6-15行使用了SFINAE機(jī)制,定義了模版類型的Test函數(shù)。具體參看【C++深陷】之“decltype”和C++模板SFINAE特性與反射機(jī)制

從名字可以知道這段代碼的目的是定義一個(gè)名為name的類型萃取器,這個(gè)萃取器的name::value是bool類型,可以判定T中是否有func函數(shù)。使用如下:

DEFINE_TYPE_TRAIT(HasByteSize, ByteSizeLong)
//定義HasByteSize的結(jié)構(gòu)體,func為ByteSizeLong

DEFINE_TYPE_TRAIT 會(huì)根據(jù)宏參數(shù) name 創(chuàng)建一個(gè)同名的類型萃取模板類,并檢查模板類型參數(shù) T 中是否包含與宏參數(shù) func 同名的方法,若包含,則模板類的 value 成員被置為 true,否則置為 false。應(yīng)該注意的是,func 在 T 中必須是公有的,否則無法被發(fā)現(xiàn)。

所以 DEFINE_TYPE_TRAIT(HasByteSize, ByteSizeLong) 的具體含義是:創(chuàng)建類型萃取模板類 HasByteSize,HasByteSize可檢查模板類型參數(shù) T 中是否包含 ByteSizeLong方法。

HasByteSize::value  \\ true 表示有A.ByteSizeLong()
//在宏定義中為name::value,即HasByteSize.value, Test(nullptr)
//這里的模版T就是A,那么4-7行Test模版中Class就是這里的A。
HasByteSize::value  \\ false 表示沒有B.ByteSizeLong()

其中A和B可以是結(jié)構(gòu)體或者類。

SFINAE機(jī)制

C++模板提供了一個(gè)SFINAE(subsitate failure is not an error)的機(jī)制(模板匹配失敗不是錯(cuò)誤),這是模板里面一個(gè)非常有意思的特性,利用這個(gè)機(jī)制可以檢查一個(gè)結(jié)構(gòu)體是否包含某個(gè)成員等操作。c++語言本身沒有提供反射機(jī)制(也有利用pb實(shí)現(xiàn)反射),利用SFINAE機(jī)制,可以實(shí)現(xiàn)類似于反射的功能。

舉例
#include#include// A類型包含size函數(shù)
struct A {int size() {  return 0;
  }
};
struct B {int Size() {return 1;
    }
};
// type trait
templatestruct HasSize {templatestatic constexpr bool Test(decltype(&Class::size)*) {return true;
    }
    templatestatic constexpr bool Test(...) {return false;
    }
    static constexpr bool value = Test(nullptr);
};

int main() {if (!HasSize::value) {std::cout<< "hello world"<

上面代碼中,HasSize中有靜態(tài)的常量value,它的初值是通過調(diào)用結(jié)構(gòu)體的靜態(tài)成員函數(shù)Test(nullptr)來初始化的。
而它有兩個(gè)Test函數(shù),且都是constexpr修飾的,這表明函數(shù)參數(shù)及返回值在編譯器就要確定下來。
正是如此,如果Class有size函數(shù),那么

static constexpr bool Test(decltype(&Class::size)*) {return true;
}

在編譯期就可以替換成功,即

static constexpr bool Test(Func *) {return true;
}

value = Test(nullptr)也就自然而然被初始化為true。否則,便會(huì)是false。
運(yùn)行上述結(jié)果,因?yàn)锽::size()不存在,可以看到最后輸出了結(jié)果。

參考

【C++深陷】之“decltype”
C++模板SFINAE特性與反射機(jī)制
由一道C++面試題引發(fā)的思考
深入探索單例設(shè)計(jì)模式:以百度 Apollo 為例
C++ type_traits和SFINAE的一點(diǎn)理解

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧

網(wǎng)頁名稱:百度apollo源碼學(xué)習(xí)(一)DEFINE-創(chuàng)新互聯(lián)
轉(zhuǎn)載來源:http://muchs.cn/article14/dpoide.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供動(dòng)態(tài)網(wǎng)站、網(wǎng)站內(nèi)鏈、網(wǎng)站收錄、定制網(wǎng)站、電子商務(wù)網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)