雷火电竞-中国电竞赛事及体育赛事平台

歡迎來到入門教程網(wǎng)!

C語言

當(dāng)前位置:主頁 > 軟件編程 > C語言 >

淺析C++中boost.variant的幾種訪問方法

來源:本站原創(chuàng)|時(shí)間:2020-01-10|欄目:C語言|點(diǎn)擊:

Boost.Variant

Variant庫包含一個(gè)不同于union的泛型類,用于在存儲(chǔ)和操作來自于不同類型的對(duì)象。這個(gè)庫的一個(gè)特點(diǎn)是支持類型安全的訪問,減少了不同數(shù)據(jù)類型的類型轉(zhuǎn)換代碼的共同問題。

Variant 庫如何改進(jìn)你的程序?

     •對(duì)用戶指定的多種類型的進(jìn)行類型安全的存儲(chǔ)和取回

     •在標(biāo)準(zhǔn)庫容器中存儲(chǔ)不同類型的方法

     •變量訪問的編譯期檢查

     •高效的、基于棧的變量存儲(chǔ)

Variant 庫關(guān)注的是對(duì)一組限定類型的類型安全存儲(chǔ)及取回,即非無類的聯(lián)合。Boost.Variant 庫與 Boost.Any 有許多共同之外,但在功能上也有不同的考慮。在每天的編程中通常都會(huì)需要用到非無類的聯(lián)合(不同的類型)。保持類型安全的一個(gè)典型方法是使用抽象基類,但這不總是可以做到的;即使可以做得,堆分配和虛擬函數(shù)的代價(jià)也可能太高。你也可以嘗試用不安全的無類類型,如 void* (它會(huì)導(dǎo)致不幸),或者是類型安全得無限制的可變類型,如 Boost.Any. 這里我們將看到 Boost.Variant,它支持限定的可變類型,即元素來自于一組支持的類型。

下面將淺談variant的幾種訪問方法,一起來學(xué)習(xí)學(xué)習(xí)吧。

使用boost::get

boost::variant<int, std::string> v;
v = "Hello world";
std::cout << boost::get<std::string>(v) << std::endl;

使用boost::get來訪問,需要給出原始類型,并且這樣做不安全,若類型錯(cuò)誤,程序?qū)?huì)拋出異常。

使用RTTI

void var_print(boost::variant<int, std::string>& v) 
{ 
  if (v.type() == typeid(int)) 
  { 
    std::cout << get<int>(v) << std::endl; 
  }
  else if (v.type() == typeid(std::string)) 
  { 
    std::cout << get<std::string>(v) << std::endl; 
  } 
  // Else do nothing
} 
int main() 
{ 
  boost::variant<int, std::string> v;
  v = "Hello world"; 
  var_print(v);
  return 0;
}

使用RTTI技術(shù)可以避免類型訪問錯(cuò)誤而程序異常的情況,但是這樣做有點(diǎn)不優(yōu)雅,每增加一個(gè)類型,都需要修改if-else結(jié)構(gòu),并且使用RTTI會(huì)對(duì)程序性能有一定影響。

使用訪問者模式

class var_visitor : public boost::static_visitor<void>
{
public:
  void operator()(int& i) const
  {
    std::cout << i << std::endl;
  }
  void operator()(std::string& str) const
  {
    std::cout << str << std::endl;
  }
};
int main() 
{ 
  boost::variant<int, std::string> v;
  v = "Hello world"; 
  boost::apply_visitor(var_visitor(), v);
  return 0;
}

使用該模式,需要定義一個(gè)類并繼承于boost::static_visitor,在類里面需要重載()操作符,通過boost::apply_visitor來訪問原始類型的值,這樣做還是有些繁瑣,每增加一個(gè)類型,都需要在var_visitor里面增加一個(gè)函數(shù),但比使用RTTI里面的修改if-else結(jié)構(gòu)好得多,因?yàn)槭褂迷L問者模式至少是遵循開放-封閉原則的,即對(duì)寫開放,對(duì)修改封閉。

使用模板函數(shù)

class var_visitor : public boost::static_visitor<void>
{
public:
  template<typename T>
  void operator()(T& i) const
  {
    std::cout << i << std::endl;
  }
};
int main() 
{ 
  boost::variant<int, std::string> v;
  v = "Hello world"; 
  boost::apply_visitor(var_visitor(), v);
  return 0;
}

operator()改成了模板函數(shù)的好處就是不用關(guān)心variant支持多少類型。

總結(jié)

以上就是這篇文章的全部內(nèi)容,希望本文的內(nèi)容對(duì)大家學(xué)習(xí)或者使用C++能有所幫助,如果有疑問大家可以留言交流。謝謝大家對(duì)我們的支持。

上一篇:C語言 實(shí)現(xiàn)歸并排序算法

欄    目:C語言

下一篇:STL priority_queue(優(yōu)先隊(duì)列)詳解

本文標(biāo)題:淺析C++中boost.variant的幾種訪問方法

本文地址:http://www.jygsgssxh.com/a1/Cyuyan/2005.html

網(wǎng)頁制作CMS教程網(wǎng)絡(luò)編程軟件編程腳本語言數(shù)據(jù)庫服務(wù)器

如果侵犯了您的權(quán)利,請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)進(jìn)行處理、任何非本站因素導(dǎo)致的法律后果,本站均不負(fù)任何責(zé)任。

聯(lián)系QQ:835971066 | 郵箱:835971066#qq.com(#換成@)

Copyright © 2002-2020 腳本教程網(wǎng) 版權(quán)所有