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

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

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

一、說(shuō)明

標(biāo)準(zhǔn)庫(kù)提供了許多容器,它們有一個(gè)共同點(diǎn):它們是同類(lèi)的。也就是說(shuō),標(biāo)準(zhǔn)庫(kù)中的容器只能存儲(chǔ)一種類(lèi)型的元素。 std::vector<int> 類(lèi)型的向量只能存儲(chǔ) int 值,而 std::vector<std::string> 類(lèi)型的向量只能存儲(chǔ)字符串。

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

嚴(yán)格來(lái)說(shuō),從C++11開(kāi)始,標(biāo)準(zhǔn)庫(kù)就提供了一個(gè)異構(gòu)容器,std::tuple。您可以對(duì)存儲(chǔ)在元組中的值使用不同的類(lèi)型。 Boost.Fusion 中的 boost:fusion::tuple 是類(lèi)似的類(lèi)型。雖然標(biāo)準(zhǔn)庫(kù)沒(méi)有提供更多,但元組只是 Boost.Fusion 的起點(diǎn)。

二、示例和代碼

示例 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 定義了一個(gè)由 int、std::string、bool 和 double 組成的元組。該元組基于 boost:fusion::tuple。在示例 50.1 中,元組隨后被實(shí)例化、初始化,并使用 boost::fusion::get() 檢索各種元素并寫(xiě)入標(biāo)準(zhǔn)輸出。函數(shù) boost::fusion::get() 類(lèi)似于 std::get(),它訪(fǎng)問(wèn) std::tuple 中的元素。

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

示例 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 中的值寫(xiě)入標(biāo)準(zhǔn)輸出。

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

示例 50.3。使用 boost::fusion::filter_view 過(guò)濾 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 提供了視圖,它像容器一樣工作但不存儲(chǔ)數(shù)據(jù)。使用視圖,可以以不同方式訪(fǎng)問(wèn)容器中的數(shù)據(jù)。視圖類(lèi)似于來(lái)自 Boost.Range 的適配器。然而,雖然來(lái)自 Boost.Range 的適配器只能應(yīng)用于一個(gè)容器,但來(lái)自 Boost.Fusion 的視圖可以跨越來(lái)自多個(gè)容器的數(shù)據(jù)。

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

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

該庫(kù)之所以稱(chēng)為 Boost.Fusion,是因?yàn)樗Y(jié)合了兩個(gè)世界:C++ 程序在運(yùn)行時(shí)處理值,在編譯時(shí)處理類(lèi)型。對(duì)于開(kāi)發(fā)人員來(lái)說(shuō),運(yùn)行時(shí)的值通常更為重要。來(lái)自標(biāo)準(zhǔn)庫(kù)的大多數(shù)工具在運(yùn)行時(shí)處理值。為了在編譯時(shí)處理類(lèi)型,使用了模板元編程。值在運(yùn)行時(shí)根據(jù)其他值進(jìn)行處理,而類(lèi)型在編譯時(shí)根據(jù)其他類(lèi)型進(jìn)行處理。 Boost.Fusion 允許您根據(jù)類(lèi)型處理值。

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

示例 50.3 使用來(lái)自 Boost.TypeTraits 的類(lèi) boost::is_integral。 boost::is_integral 是一個(gè)檢查類(lèi)型是否為整數(shù)的模板。因?yàn)楸仨殞⒛0鍏?shù)傳遞給 boost::fusion::filter_view,所以使用來(lái)自 Boost.MPL 的占位符 boost::mpl::arg<1> 來(lái)創(chuàng)建 lambda 函數(shù)。 boost::mpl::arg<1> 類(lèi)似于來(lái)自 Boost.Phoenix 的 boost::phoenix::place_holders::arg1。在示例 50.3 中,視圖 v 將僅包含元組中的 int 和 bool 元素,因此,該示例會(huì)將 10 和 true 寫(xiě)入標(biāo)準(zhǔn)輸出。

示例 50.4。使用迭代器訪(fǎng)問(wèn) 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';
}

在看過(guò) boost::fusion::tuple 和 boost::fusion::for_each() 之后,在示例 50.4 中找到迭代器應(yīng)該不足為奇。 Boost.Fusion 提供了幾個(gè)獨(dú)立的函數(shù),例如 boost::fusion::begin() 和 boost::fusion::advance(),它們的工作方式類(lèi)似于標(biāo)準(zhǔn)庫(kù)中的同名函數(shù)。

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

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

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

示例 50.5。具有 boost::fusion::vector 的異構(gòu)向量

#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';
}

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

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

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

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

此示例使用 boost::fusion::size() 獲取向量 v 和 v2 中的元素?cái)?shù)量,并將這兩個(gè)值寫(xiě)入標(biāo)準(zhǔn)輸出。該程序顯示 4 和 5。然后調(diào)用 boost::fusion::back() 獲取 v2 中的最后一個(gè)元素并將其寫(xiě)入標(biāo)準(zhǔn)輸出,在本例中值為 X。

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

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

示例 50.6。帶有 boost::fusion::map 的異構(gòu)映射

#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)建了一個(gè)異構(gòu)映射。地圖的類(lèi)型是 boost::fusion::map,由于關(guān)鍵字 auto,它沒(méi)有在示例中寫(xiě)出。

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

創(chuàng)建映射后,調(diào)用 boost::fusion::has_key() 以檢查鍵 std::string 是否存在。然后,調(diào)用 boost::fusion::at_key() 以獲取映射到該鍵的值。因?yàn)閿?shù)字 10 映射到 std::string,所以它被寫(xiě)入標(biāo)準(zhǔn)輸出。

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

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

最后,再次調(diào)用 boost::fusion::has_key() 以檢查映射是否具有鍵 std::string。因?yàn)樗驯粍h除,所以返回 false。

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

示例 50.7。結(jié)構(gòu)融合適配器

#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 提供了幾個(gè)宏,讓您可以將結(jié)構(gòu)用作 Fusion 容器。這是可能的,因?yàn)榻Y(jié)構(gòu)可以充當(dāng)異構(gòu)容器。由于宏 BOOST_FUSION_ADAPT_STRUCT,示例 50.7 定義了一個(gè)可以用作 Fusion 容器的結(jié)構(gòu)。這使得可以使用具有 boost::fusion::at() 或 boost::fusion::back() 等函數(shù)的結(jié)構(gòu)。

示例 50.8。對(duì) 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 無(wú)需使用宏即可支持 std::pair 和 boost::tuple 等結(jié)構(gòu)。您只需包含頭文件 boost/fusion/adapted.hpp(參見(jiàn)示例 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);
}

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

相關(guān)文章

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

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

    這篇文章主要給大家介紹了關(guān)于C++中const的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • 解析C語(yǔ)言與C++的編譯模型

    解析C語(yǔ)言與C++的編譯模型

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

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

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

    手把手帶你學(xué)習(xí)C++的運(yùn)算符

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

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

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

    C語(yǔ)言可變長(zhǎng)的參數(shù)列表詳解

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

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

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

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

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

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

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

    C語(yǔ)言在頭文件中定義const變量詳解

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

最新評(píng)論