欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++ STL 內(nèi) std::{bind/tuple/function} 簡(jiǎn)單實(shí)現(xiàn)

 更新時(shí)間:2020年02月20日 10:15:07   作者:Dosk 技術(shù)站  
這篇文章主要介紹了C++ STL 內(nèi) std::{bind/tuple/function} 簡(jiǎn)單實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

基本邏輯思考

首先是實(shí)現(xiàn) function,這個(gè)比較簡(jiǎn)單,重載 operator() 就好,這里只實(shí)現(xiàn)對(duì)函數(shù)指針的包裝

其次是實(shí)現(xiàn) tuple,這個(gè)會(huì)比較繞,通過(guò)模板取第一個(gè)參數(shù),然后用剩下的參數(shù)繼續(xù)生成  tuple并繼承,是一種遞歸的思想

有了 tuple 就要有 get(),這個(gè)就更比較繞了,首先是需要類(lèi)似的方式實(shí)現(xiàn)獲得 tuple 的值類(lèi)型與元組類(lèi)型,然后通過(guò)強(qiáng)制類(lèi)型轉(zhuǎn)換,獲取對(duì)應(yīng)的層級(jí)的 value

接下來(lái)是 bind,首先要解決的就是如何保存創(chuàng)建時(shí)的參數(shù)列表,這里就用到 tuple 來(lái)保存了

奇技淫巧還是運(yùn)行函數(shù)時(shí)取相應(yīng)的元組的對(duì)應(yīng)位置的值,還是類(lèi)似的方式,通過(guò)特化模板,公式是  <n, indexs...> => <n - 1, n - 1, indexs...>,比如 3 最后會(huì)生成 0 0 1 2 那么拋棄第一個(gè),并用來(lái)展開(kāi)元組,傳遞給函數(shù)指針

最重要的來(lái)了,就是如何實(shí)現(xiàn) placeholders,簡(jiǎn)單來(lái)說(shuō)就是在上一步的 operator() 增加傳入?yún)?shù),并制造成元組 r_args,然后帶進(jìn)一個(gè) _unwrap_tuple 類(lèi),這里會(huì)重載 operator[] 根據(jù)傳入數(shù)據(jù)結(jié)構(gòu),如果是 _placeholders<index> 那么取 r_args 相應(yīng)的 index 位置,否則會(huì)直接  return

代碼

不多說(shuō),還是直接放代碼,僅作為參考,有寫(xiě)的不好的地方輕噴

/*
 * Author: SpringHack - springhack@live.cn
 * Last modified: 2020-02-19 10:16:17
 * Filename: main.cpp
 * Description: Created by SpringHack using vim automatically.
 */
#include <iostream>

namespace dosk { // begin namespace dosk

// function
template <typename... T>
class function;

template <typename Result, typename... Args>
class function<Result(Args...)> {
 private:
  Result (*function_)(Args...);
 public:
  typedef Result return_type;
  function() = default;
  function(Result (*fn)(Args...)) : function_(fn) {};
  Result operator()(Args... a) {
   return function_(a...);
  }
  function& operator=(Result (*fn)(Args...)) {
   function_ = fn;
   return *this;
  }
};

// tuple
template <typename... T>
class tuple;

template <typename HEAD, typename... LIST>
class tuple<HEAD, LIST...> : public tuple<LIST...> {
 public:
  HEAD value;
  tuple(HEAD head, LIST... list) : tuple<LIST...>(list...), value(head) {};
};

template <>
class tuple<> {};

// tuple get
template <int index, typename... T>
class _tuple_type;

template <int index, typename HEAD, typename... LIST>
class _tuple_type<index, tuple<HEAD, LIST...>> {
 public:
  typedef typename _tuple_type<index - 1, tuple<LIST...>>::value_type value_type;
  typedef typename _tuple_type<index - 1, tuple<LIST...>>::tuple_type tuple_type;
};

template <typename HEAD, typename... LIST>
class _tuple_type<0, tuple<HEAD, LIST...>> {
 public:
  typedef HEAD value_type;
  typedef tuple<HEAD, LIST...> tuple_type;
};

template <int index, typename HEAD, typename... LIST>
typename _tuple_type<index, tuple<HEAD, LIST...>>::value_type get(tuple<HEAD, LIST...> t) {
 typedef typename _tuple_type<index, tuple<HEAD, LIST...>>::value_type value_type;
 typedef typename _tuple_type<index, tuple<HEAD, LIST...>>::tuple_type tuple_type;
 value_type rv = ((tuple_type)t).value;
 return rv;
}

// bind
template <size_t...>
class _tuple_index {};

template <size_t n, size_t... indexs>
class _make_indexs : public _make_indexs<n - 1, n - 1, indexs...> {};

template<size_t... indexs>
class _make_indexs<0, indexs...> {
 public:
  typedef _tuple_index<indexs...> index_type;
};

namespace placeholders {

template <size_t index>
class _placeholders {};

_placeholders<0> _1;
_placeholders<1> _2;
_placeholders<2> _3;
_placeholders<3> _4;
_placeholders<4> _5;
_placeholders<5> _6;
_placeholders<6> _7;
_placeholders<7> _8;
_placeholders<8> _9;
_placeholders<9> _10;

template <typename... RArgs>
class _unwrap_tuple {
 public:
  tuple<RArgs...> r_args; 
  _unwrap_tuple(tuple<RArgs...> r_args) : r_args(r_args) {};
  template <typename R>
  R operator[](R r) {
   return r;
  }
  template <size_t index>
  auto operator[](placeholders::_placeholders<index>) {
   return get<index>(r_args);
  }
};

};

template <typename Func, typename... Args>
class bind_t {
 public:
  typedef typename _make_indexs<sizeof...(Args)>::index_type _indexs;
  typedef typename Func::return_type return_type;
  Func func;
  tuple<Args...> args;
  bind_t(Func func, Args... args): func(func), args(args...) {}
  template <typename... RArgs>
  return_type operator()(RArgs&&... _r_args) {
   tuple<RArgs...> r_args = tuple<RArgs...>(_r_args...);
   return run(_indexs(), r_args);
  }
  template <size_t... Idx, typename... RArgs>
  return_type run(_tuple_index<Idx...>, tuple<RArgs...> r_args) {
   return func(unwrap_args<Idx>(r_args)...);
  }
  template <size_t index, typename... RArgs>
  auto unwrap_args(tuple<RArgs...> r_args) {
   placeholders::_unwrap_tuple<RArgs...> _u_a(r_args);
   auto _m_a = get<index>(args);
   return _u_a[_m_a];
  }
};

template <typename Func, typename... Args>
bind_t<Func, Args...> bind(Func& func, Args&&... args) {
 return bind_t<Func, Args...>(func, args...);
}

}; // end namespace dosk



// Test code
std::string test_func(int a, const char * b) {
 return std::to_string(a) + std::string(b);
}

std::string test_bind_args(int a, int b, int c, int d, int e) {
 return std::to_string(a) + std::to_string(b) + std::to_string(c) + std::to_string(d) + std::to_string(e);
}

int main() {
 // Test tuple
 dosk::tuple<int, const char *> t(123, "456");
 std::cout << dosk::get<0>(t) << dosk::get<1>(t) << std::endl;
 // Test function
 dosk::function<std::string(int, const char *)> closure_1 = test_func;
 std::cout << closure_1(123, "456") << std::endl;
 // Test bind
 dosk::function<std::string(int, int, int, int, int)> closure_2 = test_bind_args;
 auto binder = dosk::bind(closure_2, 1, dosk::placeholders::_2, 3, dosk::placeholders::_1, 5);
 std::cout << binder(4, 2, 0) << std::endl;
 return 0;
}

到此這篇關(guān)于C++ STL 內(nèi) std::{bind/tuple/function} 簡(jiǎn)單實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C++  std::{bind/tuple/function}內(nèi)容請(qǐng)搜素腳本之家以前的文章或下面相關(guān)文章,希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言的字符空間與非字符空間你了解嗎

    C語(yǔ)言的字符空間與非字符空間你了解嗎

    這篇文章主要介紹了C語(yǔ)言的字符空間與非字符空間,本文給大家介紹的非常詳細(xì),具有參考借鑒價(jià)值,需要的朋友可以參考下,希望能給你帶來(lái)幫助
    2021-08-08
  • C語(yǔ)言學(xué)好遞歸看這一篇就夠了

    C語(yǔ)言學(xué)好遞歸看這一篇就夠了

    遞歸指的是在函數(shù)的定義中使用函數(shù)自身的方法,舉個(gè)例子: 從前有座山,山里有座廟,廟里有個(gè)老和尚,正在給小和尚講故事呢!故事是什么呢?"從前有座山,山里有座廟,廟里有個(gè)老和尚,正在給小和尚講故事呢!故事是什么呢?"從前有座山,山里有座廟,循環(huán)下去
    2021-10-10
  • AVX2指令集優(yōu)化整形數(shù)組求和算法

    AVX2指令集優(yōu)化整形數(shù)組求和算法

    這篇文章主要為大家介紹了AVX2指令集優(yōu)化整形數(shù)組求和算法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Qt實(shí)現(xiàn)簡(jiǎn)單折線(xiàn)圖表

    Qt實(shí)現(xiàn)簡(jiǎn)單折線(xiàn)圖表

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)簡(jiǎn)單折線(xiàn)圖表,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • C語(yǔ)言實(shí)現(xiàn)圖形化打磚塊游戲

    C語(yǔ)言實(shí)現(xiàn)圖形化打磚塊游戲

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)圖形化打磚塊游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C++圖書(shū)管理系統(tǒng)程序源代碼

    C++圖書(shū)管理系統(tǒng)程序源代碼

    這篇文章主要為大家詳細(xì)介紹了C++圖書(shū)管理系統(tǒng)程序源代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • C++中for auto的用法及說(shuō)明

    C++中for auto的用法及說(shuō)明

    這篇文章主要介紹了C++中for auto的用法及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • C++中生成隨機(jī)數(shù)的方法總結(jié)

    C++中生成隨機(jī)數(shù)的方法總結(jié)

    這篇文章主要介紹了C++中生成隨機(jī)數(shù)的方法總結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-05-05
  • C++可視化角色按鍵移動(dòng)控制的實(shí)現(xiàn)

    C++可視化角色按鍵移動(dòng)控制的實(shí)現(xiàn)

    這篇文章主要介紹了C++可視化角色按鍵移動(dòng)控制的實(shí)現(xiàn),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2020-03-03
  • C++ 命名空間--namespace總結(jié)

    C++ 命名空間--namespace總結(jié)

    namespace中文意思是命名空間或者叫名字空間,下面這篇文章主要給大家介紹了關(guān)于C++中名稱(chēng)空間namespace使用的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起看看吧
    2021-09-09

最新評(píng)論