程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> VC >> 關於VC++ >> 在常規的編程任務中使用新的<tuple>庫

在常規的編程任務中使用新的<tuple>庫

編輯:關於VC++

摘要:Tuples 是大小固定的異構對象集合,它正在被添加到 C++ 標准。學習這種強大的 數據類型有助於簡化一些常規的編程任務。

C++ 標准委員會目前正在進行標准庫的更 新和增強。Tuple 類型是最近添加到 C++ 標准中的內容之一。Tuple 是一個大小固定的異構 對象集合。Tuple 類型非常強大,它有助於簡化一些常見的編程任務。

本文代碼所依賴的常規編譯器均支持 C++ 98 規范,但是目前<tulpe>庫還並不一 定是 IDE 標准庫的一部分。因此,要想使用這個庫必須到 Boost 下載並安裝。但今後的大 多數開發環境肯定都會支持<tuple>庫的。

如何模擬從一個函數中返回多個類型?如何同時進行多個值的賦值和比較?

使用 <tuple> 庫定義 tuple 對象並處理之。

1、構造和初始化

tuple 類型 tuple 類模板的特化或實例。目前的標准庫支持 0-10個元素的 tuple。每個元素可以有不同 的類型。在下面的例子中,t 被定義為 tuple 類型,它包含兩個元素,類型分別為 int 和 double:

#include <tuple>
tuple <int, double> t(1, 3.14);

為簡單起見,我不使用名字空間的限定。tuple 所在的實際名字空間及其 輔助函數是根據所使用的庫聲明的。Boost 庫在 boost::tuples 中聲明 tuple。 標准 C++ 通常會在 std 中聲明。

如果你省略初始化例程,那麼將應用默認的初始化替代:

tuple <std::string, int*> u; //initialized to: string (),0

2、輔助函數

為了得到 tuple 的元素個數,使用 tuple_size():

int sz=tuple_size <tuple <int, const double, std::string> >::value;//3

make_tuple() 用於構造 tuple 類型。該函數按照其參數創建一 個 tuple 類型:

void f(int i);
T1=make_tuple(&f); // returns: tuple<void (*)(int)>
T2=make_tuple("hi", 2); // tuple< const char (&)[3], int>

tuple_element() 函數返回單個元素的類型。 該函數以索引和 tuple 類型為參數:

//獲得第一個元素的類型
T=tuple_element <0, tuple<int, int, char> >::type;//int

如 果你需要存取實際的元素,而非類型,那麼就用 get<N>() 函數。注意 tuple 使用基 於 0 的索引。

tuple <int, double> t;
int n=get<0>(t); //獲得第一個元素
get<1>(t)=0.5; //給第二個元素賦值

3、現實世 界中的 tuple

下面讓我們考察一下 tuple 類型的應用,假設你需要實現這樣一個函 數:將某個文件名轉換為FILE * 和文件描述符。大家知道,C++ 不允許一個函數返回多個類 型的值。通常的做法是定義兩個名字稍有差別的函數來解決這個問題的,例如:

int convert_filename(const char * path);
FILE * fconvert_filename (const char * path);

POSIX 庫充滿了這樣的函數集。在這種情況下是不會用重 載機制的,因為你無法定義僅有返回值不同的函數的重載版本。例如:

int convert_filename(const char* path);
FILE* convert_filename(const char* path); //出錯

通過使用 tuple 類型來包裝兩個返回類型,你可以模擬單個函數 返回多個類型。像往常一樣,使用 typedef 來隱藏繁瑣的語法:

typedef tuple<int, FILE *> file_t;
file_t convert_filename(const char* path);

在面向對象環境中,你也可以擴展 file_t 為一個適合的 fstream 對象。

tuple 提供了一個優雅的解決方案來解決另外一個問題,就是用整型來仿真浮點值。現在 你可以借助 tuple 用兩個純粹的整型替代:

typedef tuple<__int64, int> Currency;

例如,有一個 USD 類:

class USD
{
private:
    Currency curr;
public:
    explicit USD(__int64 d=0, int c=0): curr(d,c) {}
     //..
};

注意有一個非常重要的地方是數據成員聲明為私有。該類的使 用者將不會注意其實現已經改變,因為接口完好無損。

這樣做非常好,你可能會問: “難道不能把兩個整型打包在一個定義良好的結構裡來實現嗎?”當然可以,但 是,tuple 有一個結構所沒有的優勢:那就是它已經重載了關系操作符 <、>、== 等 。因此,你可以象下面這樣輕松地比較兩個貨幣的值:

bool operator==(const USD& u1, const USD& u2)
{
   return u1.curr==u2.curr;
}

這裡,當且僅當 u1 中的每一個元素與 u2 中對應的元素相等時,tuple 重載的 == 才返回true,例如:

Currency curr1(100,99);
Currency curr2 (100,98);
Currency curr3(100,98);
bool res=curr1==curr2; //false
res=curr2==curr3; //true

4、tuple 使用之最

Tuple 有許多其它用途 。例如,你可以象下面這樣創建一個 tuple 引用和 cv 限定類型:

int i; char c;
make_tuple(ref(i),ref(c)); // tuple <int &, char&>
make_tuple(cref(i), c); // tuple <const int &, char>

ref 類 模板充當引用包裝器。同樣,cref 將引用包裝成常量(const)對象。為了簡化引用元素的 tuple 的創建過程,可以用 tie()函數:

tie(i, c); //等同於:make_tuple (ref(i), ref(c));

包含非常量引用元素的 tuple 可被用於將另外的 tuple “解包(unpack)”成實際的對象。

tie(i, c)=make_tuple(1, ''a'');

經過這樣的賦值,i=1,c=''a''。這 個技術在解包返回 tuple 的函數時很有用。

作者簡介

Danny Kalev 是一名通 過認證的系統分析師,專攻 C++ 和形式語言理論的軟件工程師。1997 年到 2000 年期間, 他是 C++ 標准委員會成員。最近他以優異成績完成了他在普通語言學研究方面的碩士論文。 業余時間他喜歡聽古典音樂,閱讀維多利亞時期的文學作品,研究 Hittite、Basque 和 Irish Gaelic 這樣的自然語言。其它興趣包括考古和地理。Danny 時常到一些 C++ 論壇並 定期為不同的 C++ 網站和雜志撰寫文章。他還在教育機構講授程序設計語言和應用語言課程 。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved