亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從元組或可變參數模板參數創建數組初始化器

從元組或可變參數模板參數創建數組初始化器

C++
小怪獸愛吃肉 2019-11-21 10:12:03
我想通過一組可變參數模板參數來描述靜態嵌入到程序代碼中(最好在ROM部分中)的持久性內存布局(例如Flash或EEPROM設備)的描述,其中在編譯時會自動計算必要的偏移量。目標是創建一個合適的數組初始化器,該初始化器可以在運行時進行迭代,而不會受到限制std::get(std::tuple),而這需要編譯時索引。第一種方法我創建了一個簡單的數據項描述符類,該類將一個特定的ID(應由客戶端以枚舉類型提供)綁定到數據布局(偏移量和大?。簍emplate    < typename ItemIdType    >struct DataItemDescBase{    const ItemIdType id;    const std::size_t size;    const std::size_t offset;    DataItemDescBase(ItemIdType id_, std::size_t size_, std::size_t offset_)    : id(id_)    , size(size_)    , offset(offset_)    {    }    DataItemDescBase(const DataItemDescBase<ItemIdType>& rhs)    : id(rhs.id)    , size(rhs.size)    , offset(rhs.offset)    {    }};客戶端應使用綁定到特定數據類型和偏移量的此類:template    < typename DataType    , typename ItemIdType    >struct DataItemDesc: public DataItemDescBase<ItemIdType>{    typedef DataType DataTypeSpec;    DataItemDesc(ItemIdType id_, std::size_t offset_ = 0)    : DataItemDescBase(id_,sizeof(DataTypeSpec),offset_)    {    }    DataItemDesc(const DataItemDesc<DataType,ItemIdType>& rhs)    : DataItemDescBase(rhs)    {    }};最后,我想使用a std::array存儲具體的數據布局:const std::array<DataItemDescBase<ItemIdType>,NumDataItems> dataItemDescriptors;對于客戶端,我想從a std::tuple或可變參數模板參數列表中提供一個數組初始化程序,因此,在編譯時,將根據前一個元素的offset +大小自動計算后續數組元素的offset。當前有效的是,客戶端可以使用以下代碼初始化數組:namespace{    static const std::array<DataItemDescBase<DataItemId::Values>,4> theDataLayout =        { { DataItemDesc<int,DataItemId::Values>             ( DataItemId::DataItem1 )        , DataItemDesc<short,DataItemId::Values>             ( DataItemId::DataItem2             , sizeof(int))        , DataItemDesc<double,DataItemId::Values>             ( DataItemId::DataItem3             , sizeof(int) + sizeof(short))        , DataItemDesc<char[10],DataItemId::Values>             ( DataItemId::DataItem4             , sizeof(int) + sizeof(short) + sizeof(double))        } };}但是讓客戶手動計算偏移量看起來容易出錯且乏味。
查看完整描述

3 回答

?
慕的地10843

TA貢獻1785條經驗 獲得超8個贊

為了進行編譯時間累積,您必須具有一個編譯時間序列。


一種簡單的方法是使用可變參數模板。每個條目將是特定元素的標識符和大小,或特定元素的標識符和類型。


頂級條目將是Layout:


template<std::size_t offset, typename Key, typename... Entries>

struct LayoutHelper {

  typedef std::tuple<> type;

};

template<typename Key, typename... Entries>

struct Layout:LayoutHelper<0, Key, Entries...> {};

每個條目將是:


template<typename Key, Key identifier, typename Data>

struct Entry {};

然后,我們執行以下操作:


template<typename Key, Key identifier, typename Data, std::size_t Offset>

struct ProcessedEntry {};


template<std::size_t offset, typename Key, Key id0, typename D0, typename... Entries>

struct LayoutHelper<offset, Key, Entry<Key, id0, D0>, Entries...>

{

    typedef typename prepend

        < ProcessedEntry< Key, id0, D0, offset >

        , typename LayoutHelper<offset+sizeof(D0), Key, Entries...>::type

        >::type type;

};

使用看起來像:


Layout< FooEnum, Entry< FooEnum, eFoo, char[10] >, Entry< FooEnum, eFoo2, double > > layout;

在編寫或找到一個prepend包含一個元素和一個tuple并在最前面添加該元素的a之后,這意味著Layout<blah>::type將包含一個tuple描述數據布局的a 。


template<typename T, typename Pack>

struct prepend;

template<typename T, template<typename...>class Pack, typename... Ts>

struct prepend<T, Pack<Ts...>> {

  typedef Pack<T, Ts...> type;

};

// use: prepend<int, std::tuple<double>::type is std::tuple<int, double>

// this removes some ::type and typename boilerplate, if it works in your compiler:

template<typename T, typename Pack>

using Prepend = typename prepend<T, Pack>::type;

然后,如果需要,可以將其解壓縮tuple為一個std::array。您可以使用索引技巧來做到這一點(堆棧溢出中有許多示例以不同的方式使用了相同的技巧)。


或者,您可以使用ProcessedEntry并添加方法來訪問數據,然后編寫一個Key搜索編譯時程序,該程序遍歷tuple,尋找匹配項Key,然后返回offsetand size(甚至類型)作為編譯時代碼。也許將an array<N, unsigned char>作為參數并執行reintepret_cast,返回對的引用data。


FooEnum通過using別名刪除重復項會很好。


查看完整回答
反對 回復 2019-11-21
?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

“然后您可以將該元組解壓縮為std :: array”,可以在此進行詳細說明。我沒有為此使用什么數組元素類型。提供的基本類型ProcessedEntry,僅僅持續了數據id,offsetsize。我需要在運行時通過id訪問特定的布局條目,以使適當的訪問器類可以訪問特定的布局條目,并計算要從具體的持久性存儲設備讀取的地址和數據大小(或者我是否需要對它進行運行時計算(不確定) ?)

查看完整回答
反對 回復 2019-11-21
?
猛跑小豬

TA貢獻1858條經驗 獲得超8個贊

“會花點時間,很難在手機上鍵入代碼”哈!您正在尋找書呆子; o),因此應為此提供一個應用程序!不,問題需要在下個星期左右找到合適的解決方案。然后看看我的更新。其實我上了幾天假節日; O)...

查看完整回答
反對 回復 2019-11-21
  • 3 回答
  • 0 關注
  • 563 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號