久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

  • <i id='QL9vt'><tr id='QL9vt'><dt id='QL9vt'><q id='QL9vt'><span id='QL9vt'><b id='QL9vt'><form id='QL9vt'><ins id='QL9vt'></ins><ul id='QL9vt'></ul><sub id='QL9vt'></sub></form><legend id='QL9vt'></legend><bdo id='QL9vt'><pre id='QL9vt'><center id='QL9vt'></center></pre></bdo></b><th id='QL9vt'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='QL9vt'><tfoot id='QL9vt'></tfoot><dl id='QL9vt'><fieldset id='QL9vt'></fieldset></dl></div>
      <bdo id='QL9vt'></bdo><ul id='QL9vt'></ul>

      <small id='QL9vt'></small><noframes id='QL9vt'>

      1. <legend id='QL9vt'><style id='QL9vt'><dir id='QL9vt'><q id='QL9vt'></q></dir></style></legend>
        <tfoot id='QL9vt'></tfoot>

        返回轉(zhuǎn)換容器的 std::transform-like 函數(shù)

        The std::transform-like function that returns transformed container(返回轉(zhuǎn)換容器的 std::transform-like 函數(shù))
        <tfoot id='OWZKm'></tfoot>

            <i id='OWZKm'><tr id='OWZKm'><dt id='OWZKm'><q id='OWZKm'><span id='OWZKm'><b id='OWZKm'><form id='OWZKm'><ins id='OWZKm'></ins><ul id='OWZKm'></ul><sub id='OWZKm'></sub></form><legend id='OWZKm'></legend><bdo id='OWZKm'><pre id='OWZKm'><center id='OWZKm'></center></pre></bdo></b><th id='OWZKm'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='OWZKm'><tfoot id='OWZKm'></tfoot><dl id='OWZKm'><fieldset id='OWZKm'></fieldset></dl></div>

            • <small id='OWZKm'></small><noframes id='OWZKm'>

            • <legend id='OWZKm'><style id='OWZKm'><dir id='OWZKm'><q id='OWZKm'></q></dir></style></legend>
                <bdo id='OWZKm'></bdo><ul id='OWZKm'></ul>

                  <tbody id='OWZKm'></tbody>
                1. 本文介紹了返回轉(zhuǎn)換容器的 std::transform-like 函數(shù)的處理方法,對大家解決問題具有一定的參考價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!

                  問題描述

                  限時送ChatGPT賬號..

                  我正在嘗試實現(xiàn)一個類似于 std::transform 算法的函數(shù),但我想創(chuàng)建并返回一個包含轉(zhuǎn)換后的輸入元素的容器,而不是通過參數(shù)獲取輸出迭代器.

                  I'm trying to implement a function similar to std::transform algorithm but instead of taking the output iterator by an argument I want to create and return a container with transformed input elements.

                  假設(shè)它名為 transform_container 并帶有兩個參數(shù):container 和 functor.它應(yīng)該返回相同的容器類型,但可能由不同的元素類型參數(shù)化(函子可以返回不同類型的元素).

                  Let's say that it's named transform_container and takes two arguments: container and functor. It should return the same container type but possibly parametrized by a different element type (the Functor can return element of different type).

                  我想使用我的函數(shù),如下例所示:

                  I'd like to use my function as in the example below:

                  std::vector<int> vi{ 1, 2, 3, 4, 5 };
                  auto vs = transform_container(vi, [] (int i) { return std::to_string(i); }); 
                  //vs will be std::vector<std::string>
                  assert(vs == std::vector<std::string>({"1", "2", "3", "4", "5"}));
                  
                  std::set<int> si{ 5, 10, 15 };
                  auto sd = transform_container(si, [] (int i) { return i / 2.; }); 
                  //sd will be of type std::set<double>
                  assert(sd == std::set<double>({5/2., 10/2., 15/2.}));
                  

                  我能夠編寫兩個函數(shù) — 一個用于 std::set,另一個用于 std::vector — 似乎可以正常工作.除了容器類型名稱之外,它們是相同的.下面列出了它們的代碼.

                  I was able two write two functions — one for std::set and one for std::vector — that seem to work properly. They are identical, except of the container typename. Their code is listed below.

                  template<typename T, typename Functor>
                  auto transform_container(const std::vector<T> &v, Functor &&f) -> std::vector<decltype(f(*v.begin()))>
                  {
                      std::vector<decltype(f(*v.begin()))> ret;
                      std::transform(std::begin(v), std::end(v), std::inserter(ret, ret.end()), f);
                      return ret;
                  }
                  
                  template<typename T, typename Functor>
                  auto transform_container(const std::set<T> &v, Functor &&f) -> std::set<decltype(f(*v.begin()))>
                  {
                      std::set<decltype(f(*v.begin()))> ret;
                      std::transform(std::begin(v), std::end(v), std::inserter(ret, ret.end()), f);
                      return ret;
                  }
                  

                  然而,當(dāng)我嘗試將它們合并為一個適用于任何容器的通用函數(shù)時,我遇到了許多問題.setvector 是類模板,因此我的函數(shù)模板必須采用模板模板參數(shù).此外,set 和 vector 模板具有不同數(shù)量的類型參數(shù),需要適當(dāng)調(diào)整.

                  However, when I attempted to merge them into a single general function that works with any container, I encountered numerous issues. The set and vector are class templates, so my function template must take a template template parameter. Moreover, set and vector templates have a different number of type parameters that needs to be properly adjusted.

                  將上述兩個函數(shù)模板泛化為適用于任何兼容容器類型的函數(shù)的最佳方法是什么?

                  What is the best way to generalize the two function templates above into a function that works with any compatible container type?

                  推薦答案

                  最簡單的情況:匹配容器類型

                  對于輸入類型與輸出類型匹配的簡單情況(我已經(jīng)意識到這不是您要問的),請?zhí)岣咭患?與其指定容器使用的類型 T,并嘗試專門針對 vector 等,只需指定容器本身的類型:

                  Simplest cases: matching container types

                  For the simple case where the input type matches the output type (which I've since realized is not what you're asking about) go one level higher. Instead of specifying the type T that your container uses, and trying to specialize on a vector<T>, etc., just specify the type of the container itself:

                  template <typename Container, typename Functor>
                  Container transform_container(const Container& c, Functor &&f)
                  {
                      Container ret;
                      std::transform(std::begin(c), std::end(c), std::inserter(ret, std::end(ret)), f);
                      return ret;
                  }
                  

                  更復(fù)雜:兼容的值類型

                  由于您想嘗試更改容器存儲的項目類型,您需要使用模板模板參數(shù),并將 T 修改為返回容器使用的類型.>

                  More complexity: compatible value types

                  Since you want to try to change the item type stored by the container, you'll need to use a template template parameter, and modify the T to that which the returned container uses.

                  template <
                      template <typename T, typename... Ts> class Container,
                      typename Functor,
                      typename T, // <-- This is the one we'll override in the return container
                      typename U = std::result_of<Functor(T)>::type,
                      typename... Ts
                  >
                  Container<U, Ts...> transform_container(const Container<T, Ts...>& c, Functor &&f)
                  {
                      Container<U, Ts...> ret;
                      std::transform(std::begin(c), std::end(c), std::inserter(ret, std::end(ret)), f);
                      return ret;
                  }
                  

                  什么是不兼容的值類型?

                  這只會讓我們走到一半.它適用于從 signedunsigned 的轉(zhuǎn)換,但是,當(dāng)使用 T=intU=std::string<解析時/code> 和處理集合,它嘗試實例化 std::set<std::string, std::less<int>, ...> 并且因此不會編譯.

                  What of incompatible value types?

                  This only gets us partway there. It works fine with a transform from signed to unsigned but, when resolving with T=int and U=std::string, and handling sets, it tries to instantiate std::set<std::string, std::less<int>, ...> and thus doesn't compile.

                  為了解決這個問題,我們想要采用任意一組參數(shù)并將 T 的實例替換為 U,即使它們是其他模板參數(shù)的參數(shù).因此 std::set> 應(yīng)該變成 std::set>; 等等.正如其他答案所建議的那樣,這涉及一些自定義模板元編程.

                  To fix this, we want to take an arbitrary set of parameters and replace instances of T with U, even if they are the parameters to other template parameters. Thus std::set<int, std::less<int>> should become std::set<std::string, std::less<std::string>>, and so forth. This involves some custom template meta programming, as suggested by other answers.

                  讓我們創(chuàng)建一個模板,將其命名為replace_type,并讓它將T 轉(zhuǎn)換為U,并且KK.首先讓我們處理一般情況.如果它不是模板類型,并且與 T 不匹配,則其類型應(yīng)保持為 K:

                  Let's create a template, name it replace_type, and have it convert T to U, and K<T> to K<U>. First let's handle the general case. If it's not a templated type, and it doesn't match T, its type shall remain K:

                  template <typename K, typename ...>
                  struct replace_type { using type = K; };
                  

                  然后是專業(yè)化.如果它不是模板類型,并且確實匹配 T,則其類型應(yīng)變?yōu)?U:

                  Then a specialization. If it's not a templated type, and it does match T, its type shall become U:

                  template <typename T, typename U>
                  struct replace_type<T, T, U> { using type = U; };
                  

                  最后一個遞歸步驟來處理模板類型的參數(shù).對于模板化類型參數(shù)中的每個類型,相應(yīng)地替換類型:

                  And finally a recursive step to handle parameters to templated types. For each type in a templated type's parameters, replace the types accordingly:

                  template <template <typename... Ks> class K, typename T, typename U, typename... Ks>
                  struct replace_type<K<Ks...>, T, U> 
                  {
                      using type = K<typename replace_type<Ks, T, U>::type ...>;
                  };
                  

                  最后更新transform_container以使用replace_type:

                  template <
                      template <typename T, typename... Ts> class Container,
                      typename Functor,
                      typename T,
                      typename U = typename std::result_of<Functor(T)>::type,
                      typename... Ts,
                      typename Result = typename replace_type<Container<T, Ts...>, T, U>::type
                  >
                  Result transform_container(const Container<T, Ts...>& c, Functor &&f)
                  {
                      Result ret;
                      std::transform(std::begin(c), std::end(c), std::inserter(ret, std::end(ret)), f);
                      return ret;
                  }
                  

                  完成了嗎?

                  這種方法的問題在于它不一定安全.如果您要從 Container 轉(zhuǎn)換為 Container,那可能沒問題.但是當(dāng)從 Container 轉(zhuǎn)換為 Container 時,另一個模板參數(shù)不應(yīng)該從 builtin_type 轉(zhuǎn)換為 是合理的>別的東西.此外,像 std::mapstd::array 這樣的替代容器給派對帶來了更多問題.

                  Is this complete?

                  The problem with this approach is it is not necessarily safe. If you're converting from Container<MyCustomType> to Container<SomethingElse>, it's likely fine. But when converting from Container<builtin_type> to Container<SomethingElse> it's plausible that another template parameter shouldn't be converted from builtin_type to SomethingElse. Furthermore, alternate containers like std::map or std::array bring more problems to the party.

                  處理std::mapstd::unordered_map 還不錯.主要問題是replace_type需要替換更多的類型.不僅有 T ->U 替換,還有一個 std::pair ->std::pair 替換.這增加了對不需要的類型替換的關(guān)注程度,因為飛行中的類型不止一種.也就是說,這就是我發(fā)現(xiàn)的工作;請注意,在測試中,我需要指定轉(zhuǎn)換我的地圖對的 lambda 函數(shù)的返回類型:

                  Handling std::map and std::unordered_map isn't too bad. The primary problem is that replace_type needs to replace more types. Not only is there a T -> U replacement, but also a std::pair<T, T2> -> std::pair<U, U2> replacement. This increases the level of concern for unwanted type replacements as there's more than a single type in flight. That said, here's what I found to work; note that in testing I needed to specify the return type of the lambda function that transformed my map's pairs:

                  // map-like classes are harder. You have to replace both the key and the key-value pair types
                  // Give a base case replacing a pair type to resolve ambiguities introduced below
                  template <typename T1, typename T2, typename U1, typename U2>
                  struct replace_type<std::pair<T1, T2>, std::pair<T1, T2>, std::pair<U1, U2>>
                  {
                      using type = std::pair<U1, U2>;
                  };
                  
                  // Now the extended case that replaces T1->U1 and pair<T1,T2> -> pair<T2,U2>
                  template <template <typename...> class K, typename T1, typename T2, typename U1, typename U2, typename... Ks>
                  struct replace_type<K<T1, T2, Ks...>, std::pair<const T1, T2>, std::pair<const U1, U2>>
                  {
                      using type = K<U1, U2, 
                          typename replace_type< 
                              typename replace_type<Ks, T1, U1>::type,
                              std::pair<const T1, T2>,
                              std::pair<const U1, U2>
                          >::type ...
                      >;
                  };
                  

                  std::array 怎么樣?

                  處理 std::array 增加了痛苦,因為它的模板參數(shù)不能在上面的模板中推導(dǎo)出來.正如 Jarod42 所指出的,這是因為它的參數(shù)包括值而不僅僅是類型.我已經(jīng)通過添加專業(yè)化并引入一個幫助程序 contained_type 來為我提取 T(旁注,每個構(gòu)造函數(shù)這更好地編寫為更簡單的 typenameContainer::value_type 并適用于我在這里討論過的所有類型).即使沒有 std::array 特化,這也允許我將我的 transform_container 模板簡化為以下內(nèi)容(即使不支持 std::array 這也可能是一個勝利):

                  What about std::array?

                  Handling std::array adds to the pain, as its template parameters cannot be deduced in the template above. As Jarod42 notes, this is due to its parameters including values instead of just types. I've gotten partway by adding specializations and introducing a helper contained_type that extracts T for me (side note, per Constructor this is better written as the much simpler typename Container::value_type and works for all types I've discussed here). Even without the std::array specializations this allows me to simplify my transform_container template to the following (this may be a win even without support for std::array):

                  template <typename T, size_t N, typename U>
                  struct replace_type<std::array<T, N>, T, U> { using type = std::array<U, N>; };
                  
                  // contained_type<C>::type is T when C is vector<T, ...>, set<T, ...>, or std::array<T, N>.
                  // This is better written as typename C::value_type, but may be necessary for bad containers
                  template <typename T, typename...>
                  struct contained_type { };
                  
                  template <template <typename ... Cs> class C, typename T, typename... Ts>
                  struct contained_type<C<T, Ts...>> { using type = T; };
                  
                  template <typename T, size_t N>
                  struct contained_type<std::array<T, N>> { using type = T; };
                  
                  template <
                      typename Container,
                      typename Functor,
                      typename T = typename contained_type<Container>::type,
                      typename U = typename std::result_of<Functor(T)>::type,
                      typename Result = typename replace_type<Container, T, U>::type
                  >
                  Result transform_container(const Container& c, Functor &&f)
                  {
                      // as above
                  }
                  

                  然而,transform_container 的當(dāng)前實現(xiàn)使用了 std::inserter,它不適用于 std::array.雖然可以進行更多的專業(yè)化,但我將把它作為模板湯練習(xí)留給感興趣的讀者.在大多數(shù)情況下,我個人會選擇不支持 std::array.

                  However the current implementation of transform_container uses std::inserter which does not work with std::array. While it's possible to make more specializations, I'm going to leave this as a template soup exercise for an interested reader. I would personally choose to live without support for std::array in most cases.

                  查看累積直播示例

                  完全披露:雖然這種方法受到 Ali 引用 Kerrek SB 答案的影響,但我沒有設(shè)法讓它在 Visual Studio 2013 中工作,所以我自己構(gòu)建了上述替代方案.非常感謝 Kerrek SB 的原始答案 的部分內(nèi)容仍然是必要的,以及來自 Constructor 和 Jarod42 的刺激和鼓勵.

                  Full disclosure: while this approach was influenced by Ali's quoting of Kerrek SB's answer, I didn't manage to get that to work in Visual Studio 2013, so I built the above alternative myself. Many thanks to parts of Kerrek SB's original answer are still necessary, as well as to prodding and encouragement from Constructor and Jarod42.

                  這篇關(guān)于返回轉(zhuǎn)換容器的 std::transform-like 函數(shù)的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

                  【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請聯(lián)系我們刪除處理,感謝您的支持!

                  相關(guān)文檔推薦

                  Why do two functions have the same address?(為什么兩個函數(shù)的地址相同?)
                  Why the initializer of std::function has to be CopyConstructible?(為什么 std::function 的初始化程序必須是可復(fù)制構(gòu)造的?)
                  mixing templates with polymorphism(混合模板與多態(tài)性)
                  When should I use the keyword quot;typenamequot; when using templates(我什么時候應(yīng)該使用關(guān)鍵字“typename?使用模板時)
                  Dependent name resolution amp; namespace std / Standard Library(依賴名稱解析命名空間 std/標(biāo)準(zhǔn)庫)
                  gcc can compile a variadic template while clang cannot(gcc 可以編譯可變參數(shù)模板,而 clang 不能)
                  <tfoot id='flwM1'></tfoot>

                2. <legend id='flwM1'><style id='flwM1'><dir id='flwM1'><q id='flwM1'></q></dir></style></legend>
                      <i id='flwM1'><tr id='flwM1'><dt id='flwM1'><q id='flwM1'><span id='flwM1'><b id='flwM1'><form id='flwM1'><ins id='flwM1'></ins><ul id='flwM1'></ul><sub id='flwM1'></sub></form><legend id='flwM1'></legend><bdo id='flwM1'><pre id='flwM1'><center id='flwM1'></center></pre></bdo></b><th id='flwM1'></th></span></q></dt></tr></i><div class="qwawimqqmiuu" id='flwM1'><tfoot id='flwM1'></tfoot><dl id='flwM1'><fieldset id='flwM1'></fieldset></dl></div>

                        <bdo id='flwM1'></bdo><ul id='flwM1'></ul>

                            <tbody id='flwM1'></tbody>

                          <small id='flwM1'></small><noframes id='flwM1'>

                            主站蜘蛛池模板: 一区二区三区免费 | 欧美福利精品 | 九色视频网站 | av中文字幕在线 | 国产一区二区三区四区在线观看 | 美女视频h | 亚洲精品视频观看 | 午夜手机在线视频 | 国产日韩欧美91 | 免费一级做a爰片久久毛片潮喷 | 久草免费在线视频 | 亚洲成人一区二区 | 国产精品一区二区三区免费观看 | 九九热在线视频 | 久久综合影院 | 草草精品 | 色天天综合| 91伊人网| 国产专区视频 | 欧美日韩国产一区二区三区 | 欧美久久精品一级黑人c片 91免费在线视频 | 日日干干| 天天综合久久网 | 欧美99 | 日韩中文字幕在线 | 久久久久se | 精品久久久久久久 | 色欧美综合 | 91精品国产综合久久久亚洲 | 成人在线免费观看视频 | 第一福利社区1024 | 午夜影院官网 | 国产免费一区二区 | 超碰超碰 | 天天弄 | 久久久精品 | 日韩一二区在线观看 | 亚洲第一天堂无码专区 | 99re在线视频| 九九综合 | 超黄视频网站 |