C++模板 index_sequence使用示例詳解
引言
integer_sequence
是 c++ 14中新增加的一個(gè)元編程工具
其衍生出來(lái)的還有如 index_sequence
、make_index_sequence
、index_sequence_for
等輔助工具
現(xiàn)在,讓我們來(lái)淺嘗一下這些東西吧!
integer_sequence
integer_sequence
其實(shí)沒(méi)有什么特殊的,就是一個(gè)類
只不過(guò)他是index_sequence
的基礎(chǔ)
template<typename _Tp, _Tp... _Idx> struct integer_sequence { typedef _Tp value_type; static constexpr size_t size() noexcept { return sizeof...(_Idx); } };
index_sequence
index_sequence
會(huì)在編譯期生成一個(gè)從0開(kāi)始的序列
然后你就可以對(duì)其進(jìn)行一些奇奇怪怪的操作
template <size_t... N> void print(std::index_sequence<N...>) { std::vector<int> res; (void)std::initializer_list<int>{ ((res.push_back(N), std::cout << N << " "), 0)...}; std::for_each(res.begin(), res.end(), [](int x) {std::cout << x << " ";}); } int main() { auto t = std::make_index_sequence<10>(); print(t); return 0; }
比如 ((res.push_back(N), std::cout << N << " "), 0)...
這句話,就會(huì)在編譯期被展開(kāi)
這里展開(kāi)在了一個(gè)初始化列表中,小技巧
make_index_sequence
那么,index_sequence 是如何生成的呢?
有兩種形式
- 編譯器內(nèi)建
- 遞歸式的生成
第二種方式嘛還是用到了元編程的慣用伎倆,特化,遞歸式的編程
template <int... N> struct index_seq {}; template <int N, int... M> struct make_index_seq : public make_index_seq<N - 1, N - 1, M...> {}; template <int... M> struct make_index_seq<0, M...> : public index_seq<M...> {};
對(duì)齊使用也是一樣的形式
template <int... N> void print(index_seq<N...>) { (void)std::initializer_list<int>{((std::cout << N << " "), 0)...}; } int main() { auto r = make_index_seq<100>(); print(r); return 0; }
使用場(chǎng)景
剛才,看見(jiàn)了print去打印的時(shí)候打印了 0-(N-1)的元素
那么,這個(gè)行為是在編譯期展開(kāi)的,我們就可以用到其他需要常量的地方
比如一個(gè)簡(jiǎn)單的需求:
打印tuple
!
template <typename T, typename F, int...N> void exec_for_tuple(const T& tup, F&& func, index_seq<N...>) { (void)std::initializer_list<int> { (func(std::get<N>(tup)), 0)... }; } template <typename Func, typename ...Arg> void for_tuple(Func&& func, std::tuple<Arg...> tuple) { exec_for_tuple(tuple, std::forward<Func>(func), make_index_seq<sizeof...(Arg)>()); }
exec_for_tuple
部分應(yīng)該非常好懂,但是為什么中間還要再轉(zhuǎn)發(fā)一層呢?
因?yàn)?code>tuple元素的個(gè)數(shù)我們不能直接獲取到,我們寫(xiě)的又要是一個(gè)通用的函數(shù)
所以要通過(guò) sizeof...(arg)
這種伎倆來(lái)將其元素個(gè)數(shù)計(jì)算出來(lái)
如何調(diào)用呢?
如下所示:
std::tuple<int, int, double> tuple{1, 2, 3.0}; for_tuple([](auto t) { std::cout << t << " "; }, tuple);
index_sequence_for
那么,看到現(xiàn)在,你知道 index_sequence_for
又是何物嗎?
其實(shí)吧,剛才就已經(jīng)見(jiàn)過(guò) index_sequence_for
這個(gè)東西了
其實(shí)就是計(jì)算可變長(zhǎng)模板參數(shù)的個(gè)數(shù),然后將其長(zhǎng)度做成一個(gè)sequence出來(lái)
template<typename... _Types> using index_sequence_for = make_index_seq<sizeof...(_Types)>;
結(jié)語(yǔ)
index_sequence
是一個(gè)不起眼的家伙,可能你平時(shí)都不會(huì)去了解它,但是這個(gè)東西的用途還是有很多的,你想想,編譯器制造一串序列的能力,在tuple這種模板中,使用其是不是更加方便了,在bind這種模板中的參數(shù)上,若是使用它,是不是更加靈活好些了。
其實(shí)和tuple一個(gè)道理,在平常編程中,你也許不會(huì)使用它,但是在模板編程中,這是比較好的一個(gè)工具。
以上就是C++模板 index_sequence使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于C++模板index_sequence的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
簡(jiǎn)單了解C++語(yǔ)言中的二元運(yùn)算符和賦值運(yùn)算符
這篇文章主要介紹了C++語(yǔ)言中的二元運(yùn)算符和賦值運(yùn)算符,文中列出了可重載的運(yùn)算符列表,需要的朋友可以參考下2016-01-01C語(yǔ)言代碼實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言代碼實(shí)現(xiàn)學(xué)生成績(jī)管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)猜數(shù)字游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11詳解C語(yǔ)言中的錯(cuò)誤報(bào)告errno與其相關(guān)應(yīng)用方法
這篇文章主要介紹了C語(yǔ)言中的錯(cuò)誤報(bào)告errno與其相關(guān)應(yīng)用方法,包括errno和strerror以及perror的介紹,需要的朋友可以參考下2015-08-08C++ 中動(dòng)態(tài)鏈接庫(kù)--導(dǎo)入和導(dǎo)出的實(shí)例詳解
這篇文章主要介紹了C++ 中動(dòng)態(tài)鏈接庫(kù)--導(dǎo)入和導(dǎo)出的實(shí)例詳解的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09