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

C++ Boost Fusion創(chuàng)建異構容器詳解

 更新時間:2022年11月22日 08:42:19   作者:無水先生  
Boost.Fusion 使創(chuàng)建異構容器成為可能。例如,您可以創(chuàng)建一個向量,其第一個元素是 int,第二個元素是字符串。此外,Boost.Fusion 提供了處理異構容器的算法。您可以將 Boost.Fusion 視為異構容器的標準庫

一、說明

標準庫提供了許多容器,它們有一個共同點:它們是同類的。也就是說,標準庫中的容器只能存儲一種類型的元素。 std::vector<int> 類型的向量只能存儲 int 值,而 std::vector<std::string> 類型的向量只能存儲字符串。

Boost.Fusion 使創(chuàng)建異構容器成為可能。例如,您可以創(chuàng)建一個向量,其第一個元素是 int,第二個元素是字符串。此外,Boost.Fusion 提供了處理異構容器的算法。您可以將 Boost.Fusion 視為異構容器的標準庫。

嚴格來說,從C++11開始,標準庫就提供了一個異構容器,std::tuple。您可以對存儲在元組中的值使用不同的類型。 Boost.Fusion 中的 boost:fusion::tuple 是類似的類型。雖然標準庫沒有提供更多,但元組只是 Boost.Fusion 的起點。

二、示例和代碼

示例 50.1。處理融合元組

#include <boost/fusion/tuple.hpp>
#include <string>
#include <iostream>
using namespace boost::fusion;
int main()
{
  typedef tuple<int, std::string, bool, double> tuple_type;
  tuple_type t{10, "Boost", true, 3.14};
  std::cout << get<0>(t) << '\n';
  std::cout << get<1>(t) << '\n';
  std::cout << std::boolalpha << get<2>(t) << '\n';
  std::cout << get<3>(t) << '\n';
}

Example50.1

示例 50.1 定義了一個由 int、std::string、bool 和 double 組成的元組。該元組基于 boost:fusion::tuple。在示例 50.1 中,元組隨后被實例化、初始化,并使用 boost::fusion::get() 檢索各種元素并寫入標準輸出。函數(shù) boost::fusion::get() 類似于 std::get(),它訪問 std::tuple 中的元素。

融合元組與標準庫中的元組沒有區(qū)別。因此,Boost.Fusion 提供函數(shù) boost::fusion::make_tuple() 就不足為奇了,它的工作方式類似于 std::make_tuple()。但是,Boost.Fusion 提供了超出標準庫中所提供功能的附加功能。

示例 50.2。使用 boost::fusion::for_each() 迭代元組

#include <boost/fusion/tuple.hpp>
#include <boost/fusion/algorithm.hpp>
#include <string>
#include <iostream>
using namespace boost::fusion;
struct print
{
  template <typename T>
  void operator()(const T &t) const
  {
    std::cout << std::boolalpha << t << '\n';
  }
};
int main()
{
  typedef tuple<int, std::string, bool, double> tuple_type;
  tuple_type t{10, "Boost", true, 3.14};
  for_each(t, print{});
}

示例 50.2 介紹了算法 boost::fusion::for_each(),它迭代 Fusion 容器。此處使用該函數(shù)將元組 t 中的值寫入標準輸出。

boost::fusion::for_each() 旨在像 std::for_each() 一樣工作。 std::for_each() 僅迭代同類容器,而 boost::fusion::for_each() 適用于異構容器。您將容器而不是迭代器傳遞給 boost::fusion::for_each()。如果您不想遍歷容器中的所有元素,可以使用視圖。

示例 50.3。使用 boost::fusion::filter_view 過濾 Fusion 容器

#include <boost/fusion/tuple.hpp>
#include <boost/fusion/view.hpp>
#include <boost/fusion/algorithm.hpp>
#include <boost/type_traits.hpp>
#include <boost/mpl/arg.hpp>
#include <string>
#include <iostream>
using namespace boost::fusion;
struct print
{
  template <typename T>
  void operator()(const T &t) const
  {
    std::cout << std::boolalpha << t << '\n';
  }
};
int main()
{
  typedef tuple<int, std::string, bool, double> tuple_type;
  tuple_type t{10, "Boost", true, 3.14};
  filter_view<tuple_type, boost::is_integral<boost::mpl::arg<1>>> v{t};
  for_each(v, print{});
}

Boost.Fusion 提供了視圖,它像容器一樣工作但不存儲數(shù)據(jù)。使用視圖,可以以不同方式訪問容器中的數(shù)據(jù)。視圖類似于來自 Boost.Range 的適配器。然而,雖然來自 Boost.Range 的適配器只能應用于一個容器,但來自 Boost.Fusion 的視圖可以跨越來自多個容器的數(shù)據(jù)。

示例 50.3 使用類 boost::fusion::filter_view 來過濾元組 t。過濾器指示 boost::fusion::for_each() 僅寫入基于整數(shù)類型的元素。

boost::fusion::filter_view 期望第一個模板參數(shù)是要過濾的容器類型。第二個模板參數(shù)必須是過濾元素的謂詞。謂詞必須根據(jù)元素的類型過濾元素。

該庫之所以稱為 Boost.Fusion,是因為它結合了兩個世界:C++ 程序在運行時處理值,在編譯時處理類型。對于開發(fā)人員來說,運行時的值通常更為重要。來自標準庫的大多數(shù)工具在運行時處理值。為了在編譯時處理類型,使用了模板元編程。值在運行時根據(jù)其他值進行處理,而類型在編譯時根據(jù)其他類型進行處理。 Boost.Fusion 允許您根據(jù)類型處理值。

傳遞給 boost::fusion::filter_view 的第二個模板參數(shù)是一個謂詞,它將應用于元組中的每個類型。謂詞需要一個類型作為參數(shù),如果該類型應該是視圖的一部分,則返回 true。如果返回 false,則過濾掉該類型。

示例 50.3 使用來自 Boost.TypeTraits 的類 boost::is_integral。 boost::is_integral 是一個檢查類型是否為整數(shù)的模板。因為必須將模板參數(shù)傳遞給 boost::fusion::filter_view,所以使用來自 Boost.MPL 的占位符 boost::mpl::arg<1> 來創(chuàng)建 lambda 函數(shù)。 boost::mpl::arg<1> 類似于來自 Boost.Phoenix 的 boost::phoenix::place_holders::arg1。在示例 50.3 中,視圖 v 將僅包含元組中的 int 和 bool 元素,因此,該示例會將 10 和 true 寫入標準輸出。

示例 50.4。使用迭代器訪問 Fusion 容器中的元素

#include <boost/fusion/tuple.hpp>
#include <boost/fusion/iterator.hpp>
#include <boost/mpl/int.hpp>
#include <string>
#include <iostream>
using namespace boost::fusion;
int main()
{
  typedef tuple<int, std::string, bool, double> tuple_type;
  tuple_type t{10, "Boost", true, 3.14};
  auto it = begin(t);
  std::cout << *it << '\n';
  auto it2 = advance<boost::mpl::int_<2>>(it);
  std::cout << std::boolalpha << *it2 << '\n';
}

在看過 boost::fusion::tuple 和 boost::fusion::for_each() 之后,在示例 50.4 中找到迭代器應該不足為奇。 Boost.Fusion 提供了幾個獨立的函數(shù),例如 boost::fusion::begin() 和 boost::fusion::advance(),它們的工作方式類似于標準庫中的同名函數(shù)。

迭代器要遞增的步數(shù)作為模板參數(shù)傳遞給 boost::fusion::advance()。該示例再次使用來自 Boost.MPL 的 boost::mpl::int_。

boost::fusion::advance() 返回一個與傳遞給函數(shù)的迭代器類型不同的迭代器。這就是示例 50.4 使用第二個迭代器 it2 的原因。您不能將 boost::fusion::advance() 的返回值分配給第一個迭代器 it。示例 50.4 將 10 和 true 寫入標準輸出。

除了示例中介紹的函數(shù)之外,Boost.Fusion 還提供了與迭代器一起使用的其他函數(shù)。其中包括:boost::fusion::end()、boost::fusion::distance()、boost::fusion::next() 和 boost::fusion::prior()。

示例 50.5。具有 boost::fusion::vector 的異構向量

#include <boost/fusion/container.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/mpl/int.hpp>
#include <string>
#include <iostream>
using namespace boost::fusion;
int main()
{
  typedef vector<int, std::string, bool, double> vector_type;
  vector_type v{10, "Boost", true, 3.14};
  std::cout << at<boost::mpl::int_<0>>(v) << '\n';
  auto v2 = push_back(v, 'X');
  std::cout << size(v) << '\n';
  std::cout << size(v2) << '\n';
  std::cout << back(v2) << '\n';
}

到目前為止,我們只看到了一個異構容器,boost::fusion::tuple。示例 50.5 引入了另一個容器,boost::fusion::vector。

boost::fusion::vector 是一個向量:通過索引訪問元素。訪問不是使用運算符 operator[] 實現(xiàn)的。相反,它是使用獨立函數(shù) boost::fusion::at() 實現(xiàn)的。索引作為用 boost::mpl::int_ 包裝的模板參數(shù)傳遞。

此示例將一個 char 類型的新元素添加到向量中。這是通過獨立函數(shù) boost::fusion::push_back() 完成的。兩個參數(shù)被傳遞給 boost::fusion::push_back():要添加元素的向量和要添加的值。

boost::fusion::push_back() 返回一個新向量。矢量 v 沒有改變。新向量是添加了元素的原始向量的副本。

此示例使用 boost::fusion::size() 獲取向量 v 和 v2 中的元素數(shù)量,并將這兩個值寫入標準輸出。該程序顯示 4 和 5。然后調用 boost::fusion::back() 獲取 v2 中的最后一個元素并將其寫入標準輸出,在本例中值為 X。

如果您更仔細地查看示例 50.5,您會注意到 boost::fusion::tuple 和 boost::fusion::vector 之間沒有區(qū)別;他們是一樣的。因此,示例 50.5 也可以與 boost::fusion::tuple 一起使用。

Boost.Fusion 提供了額外的異構容器,包括:boost::fusion::deque、boost::fusion::list 和 boost::fusion::set。示例 50.6 引入了 boost::fusion::map,它是鍵/值對的容器。

示例 50.6。帶有 boost::fusion::map 的異構映射

#include <boost/fusion/container.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/fusion/algorithm.hpp>
#include <string>
#include <iostream>
using namespace boost::fusion;
int main()
{
  auto m = make_map<int, std::string, bool, double>("Boost", 10, 3.14, true);
  if (has_key<std::string>(m))
    std::cout << at_key<std::string>(m) << '\n';
  auto m2 = erase_key<std::string>(m);
  auto m3 = push_back(m2, make_pair<float>('X'));
  std::cout << std::boolalpha << has_key<std::string>(m3) << '\n';
}

Example50.6

示例 50.6 使用 boost::fusion::map() 創(chuàng)建了一個異構映射。地圖的類型是 boost::fusion::map,由于關鍵字 auto,它沒有在示例中寫出。

boost::fusion::map 類型的映射像 std::map 一樣存儲鍵/值對。但是,F(xiàn)usion 映射中的鍵是類型。鍵/值對由一個類型和一個映射到該類型的值組成。該值可能是與鍵不同的類型。在示例 50.6 中,字符串“Boost”映射到鍵 int。

創(chuàng)建映射后,調用 boost::fusion::has_key() 以檢查鍵 std::string 是否存在。然后,調用 boost::fusion::at_key() 以獲取映射到該鍵的值。因為數(shù)字 10 映射到 std::string,所以它被寫入標準輸出。

然后使用 boost::fusion::erase_key() 擦除鍵/值對。這不會改變地圖 m。 boost::fusion::erase_key() 返回一個新映射,該映射缺少已擦除的鍵/值對。

對 boost::fusion::push_back() 的調用將一個新的鍵/值對添加到映射中。鍵是浮點數(shù),值是“X”。調用 boost::fusion::make_pair() 來創(chuàng)建新的鍵/值對。此函數(shù)類似于 std::make_pair()。

最后,再次調用 boost::fusion::has_key() 以檢查映射是否具有鍵 std::string。因為它已被刪除,所以返回 false。

請注意,在調用 boost::fusion::at_key() 之前,您不需要調用 boost::fusion::has_key() 來檢查密鑰是否存在。如果傳遞給 boost::fusion::at_key() 的鍵在映射中不存在,則會出現(xiàn)編譯器錯誤。

示例 50.7。結構融合適配器

#include <boost/fusion/adapted.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/mpl/int.hpp>
#include <iostream>
struct strct
{
  int i;
  double d;
};
BOOST_FUSION_ADAPT_STRUCT(strct,
  (int, i)
  (double, d)
)
using namespace boost::fusion;
int main()
{
  strct s = {10, 3.14};
  std::cout << at<boost::mpl::int_<0>>(s) << '\n';
  std::cout << back(s) << '\n';
}

Boost.Fusion 提供了幾個宏,讓您可以將結構用作 Fusion 容器。這是可能的,因為結構可以充當異構容器。由于宏 BOOST_FUSION_ADAPT_STRUCT,示例 50.7 定義了一個可以用作 Fusion 容器的結構。這使得可以使用具有 boost::fusion::at() 或 boost::fusion::back() 等函數(shù)的結構。

示例 50.8。對 std::pair 的融合支持

#include <boost/fusion/adapted.hpp>
#include <boost/fusion/sequence.hpp>
#include <boost/mpl/int.hpp>
#include <utility>
#include <iostream>
using namespace boost::fusion;
int main()
{
  auto p = std::make_pair(10, 3.14);
  std::cout << at<boost::mpl::int_<0>>(p) << '\n';
  std::cout << back(p) << '\n';
}

Boost.Fusion 無需使用宏即可支持 std::pair 和 boost::tuple 等結構。您只需包含頭文件 boost/fusion/adapted.hpp(參見示例 50.8)。

#include <boost/math/constants/constants.hpp>
#include <iostream>
struct animal
{
    std::string name;
    int legs;
    bool has_tail;
};
struct important_numbers
{
    const float pi = boost::math::constants::pi<float>();
    const double e = boost::math::constants::e<double>();
};
template <class T>
void debug(const T &t)
{
    // TODO: Write member variables of t to standard output.
}
int main()
{
    animal a{ "cat", 4, true };
    debug(a);
    important_numbers in;
    debug(in);
}

到此這篇關于C++ Boost Fusion創(chuàng)建異構容器詳解的文章就介紹到這了,更多相關C++ Boost Fusion內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 一文讓你徹底明白C++中的const

    一文讓你徹底明白C++中的const

    這篇文章主要給大家介紹了關于C++中const的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-11-11
  • 解析C語言與C++的編譯模型

    解析C語言與C++的編譯模型

    C++繼承了C的編譯模型,C語言的編譯鏈接模型相對簡潔,但C++繼承了這些機制之后變得更加復雜難以理解,這里就來帶大家簡要解析C語言與C++的編譯模型
    2016-05-05
  • C++11實現(xiàn)字符串分割的示例

    C++11實現(xiàn)字符串分割的示例

    本文主要介紹了C++11實現(xiàn)字符串分割的示例,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • 手把手帶你學習C++的運算符

    手把手帶你學習C++的運算符

    這篇文章主要為大家介紹了C++運算符,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助,希望能夠給你帶來幫助
    2021-11-11
  • C++中函數(shù)的用法小結

    C++中函數(shù)的用法小結

    這篇文章主要為大家分享下本人在閱讀《C++ Primer》函數(shù)一章時的讀書總結,需要的朋友可以參考下
    2014-02-02
  • C語言可變長的參數(shù)列表詳解

    C語言可變長的參數(shù)列表詳解

    這篇文章主要為大家介紹了C語言可變長的參數(shù)列表,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-01-01
  • 詳解在C++中顯式默認設置的函數(shù)和已刪除的函數(shù)的方法

    詳解在C++中顯式默認設置的函數(shù)和已刪除的函數(shù)的方法

    這篇文章主要介紹了在C++中顯式默認設置的函數(shù)和已刪除的函數(shù)的方法,文中講到了C++11標準中的新特性,需要的朋友可以參考下
    2016-01-01
  • Qt繪制圖表的實現(xiàn)

    Qt繪制圖表的實現(xiàn)

    Qt中提供了強大的2D繪圖系統(tǒng),可以使用同一API實現(xiàn)在屏幕和繪圖設備上進行繪制,本文就詳細的介紹了Qt繪制坐標圖、柱狀圖、折線圖、餅圖、曲線圖、散點圖等,感興趣的可以了解一下
    2021-05-05
  • c++ For循環(huán)執(zhí)行順序流程圖解

    c++ For循環(huán)執(zhí)行順序流程圖解

    for 循環(huán)允許您編寫一個執(zhí)行特定次數(shù)的循環(huán)的重復控制結構,這里為大家分享一下具體的執(zhí)行流程,需要的朋友可以參考下
    2021-10-10
  • C語言在頭文件中定義const變量詳解

    C語言在頭文件中定義const變量詳解

    這篇文章主要介紹了C語言在頭文件中定義const變量詳解的相關資料,需要的朋友可以參考下
    2017-05-05

最新評論