【UE4】元組(TTuple)原來是這樣的
????最近正好在了解UFunction的反射調(diào)用,發(fā)現(xiàn)用到一個東西叫元組(Tuple),方便好用,所以就花時間仔細(xì)看了看。東西雖然很簡單,但分析它還是花了點時間,有點繞彎彎,理解起來有點難度,所以把分析過程記錄在這里。
TTuple展開
? ? TTuple是一個模板結(jié)構(gòu)體,可以很方便的定義一塊連續(xù)的內(nèi)存。并且該struct中有多個按順序的不同類型的值。如下面代碼所定義:TTuple<FString, int32, int32, FString> TupleValue;當(dāng)然在UE中,也經(jīng)常用在不定長參數(shù)模板函數(shù)或類中。
????TTuple看似很復(fù)雜,當(dāng)我們在閱讀先關(guān)代碼時,感覺很難看懂。那也許是我們看它的角度不對。接下來,本文就帶大家一起看看元組(TTuple)。
????既然是模板,那就應(yīng)該先搞清楚展開之后的廬山真面目。定義一個元祖變量TTuple<int32, int32, int32&, int32&> TestTuple;展開之后就變成如下代碼(類名可能對應(yīng)不上,只是示意作用)
對a取地址(或者&TestTuple),都是取到最終的struct首地址??梢院芊奖愕耐ㄟ^內(nèi)存復(fù)制、寫入來操作該結(jié)構(gòu)體。在前面代碼中TTuple<TArgs...>InParams(Forward<TArgs>(Args)...);用不定長模板參數(shù)直接構(gòu)造元組(TTuple),后面我們將看到通過這種方法初始化函數(shù)調(diào)用的入?yún)?shù)據(jù)。
閱讀TTuple源碼可以看到定義如下
Types為前面定義是傳入的int32,int32,int32&,int32&,可以看到TTuple繼承自TTupleBase。TTupleBase有兩個模板參數(shù),第一個為TMakeIntegerSequence<uint32,sizeof...(Types)>,第二個為Types...
通過上面代碼可以看到TMakeIntegerSequence長啥子樣?本質(zhì)就是,通過遞歸的方式套用TMakeIntegerSequence,最后由TConcat將這些遞歸之后的內(nèi)容組合在一起。T為類型uint32, N為sizeof...(Types)。在本例中N=4。
第一次調(diào)用TMakeIntegerSequence,Type變成如下結(jié)果
分別將后面兩個也展開,Type變成如下結(jié)果
TMakeIntegerSequence<uint32,1>找到自己的模板后變成TIntegerSequence<uint32,0>
帶入之后Type有如下變化
展開內(nèi)部的TConcat
帶入到上一步,Type變?yōu)?/p>
到此,TTuple的第一個模板參數(shù)全部完成,接下來就是第二個模板參數(shù)Types...,在本文的例子中展開之后分別是int32, int32, int32&, int32&
所以,得到新的struct

訪問Tuple中的值
????如果Tuple中只有一個元素,可以直接通過Value訪問。如果有多個元素可以調(diào)用Get方法訪問。這里詳細(xì)看看Get方法。
需要傳入index下標(biāo),指明要訪問第幾個元素。
可以看到關(guān)鍵代碼就是
同樣的,我們用前面的struct A : B1, B2, B3, B4{}作為例子:
所以,最后基本就是直接裝換為對應(yīng)的父類類型,然后獲取他的Value值。這部分沒有詳細(xì)過一遍模板的展開過程,閱讀者可以按第一部分的過程自己逐個展開、替換。
后面有機會,總結(jié)一篇反射調(diào)用UFUNCTION。(貌似里面的坑還不少)。