boost.png (6897 bytes)頭文件 boost/utility.hpp

頭文件 <boost/utility.hpp> 的所有內容都位於名字空間 boost.

目錄

函數模板 checked_delete() 和 checked_array_delete()

請看 單獨的文檔

函數模板 next() 和 prior()

有些數據類型,如C++標準庫的前向和雙向迭代器,不提供 operator+() 或 operator-() 的加法和減法。這意味著即使已經有了 operator++() 或 operator--(),但如果想不修改原值而獲得 next 或 prior 值就需要一個臨時存儲。這也意味著在一個模板中編寫象 itr+1 這樣的代碼就限制了迭代器類別必須是隨機訪問迭代器。

next() 和 prior() 函數提供了一個繞過這些問題的簡單方法:

template <class T>
T next(T x) { return ++x; }

template <class T, class Distance>
T next(T x, Distance n)
{
std::advance(x, n);
return x;
}

template <class T>
T prior(T x) { return --x; }

template <class T, class Distance>
T prior(T x, Distance n)
{
std::advance(x, -n);
return x;
}

用法也很簡單:

const std::list<T>::iterator p = get_some_iterator();
const std::list<T>::iterator prev = boost::prior(p);
const std::list<T>::iterator next = boost::next(prev, 2);

從給定迭代器移動的距離應以絕對值的形式指定。例如,給定迭代器 p 之前的第四個迭代器應寫為 prior(p, 4).

這是由 Dave Abrahams 貢獻的。兩參數版本則是來自 Daniel Walker.

類 noncopyable

類 noncopyable 是一個基類。當你想禁止複製構造和複製賦值時,可以從 noncopyable 派生你的類。

有些對象,持有象文件和網絡連接這樣的複雜資源,它們沒有明確的複製語義。有時候可能會有複製語義,不過也只有非常有限的用處,而且要 正確地實現也非常困難。有時候你是在實現一個沒有複製必要的類,你也不想花時間去寫這些函數。從 noncopyable 進行派生可以防止其它隱式生成的函數(它們不具備正確的語義)成為其它程序員的陷阱。

處理這一情況的傳統方法是聲明一個私有的複製構造函數和賦值函數,並寫明為什麼這樣做。不過從 noncopyable 進行派生更簡單也更清晰,不需要其它說明。

程序 noncopyable_test.cpp 可用於驗證類 noncopyable 是否工作正確。它已經成功地運行於 GCC 2.95, Metrowerks CodeWarrior 5.0, 和 Microsoft Visual C++ 6.0 sp 3.

本庫由 Dave Abrahams 貢獻。

例子

// 在你的某個頭文件中 ...
#include <boost/utility.hpp>

class ResourceLadenFileSystem : boost::noncopyable {
...

原理

類 noncopyable 帶有保護的構造函數和析構函數,以強調它只被用作基類。Dave Abrahams 提到了增加(即使是簡單的內聯函數)析構函數聲明對於編譯器優化的影響。他說 "可能這個擔心是錯誤的,因為 noncopyable 在大多數情況下是用於擁有資源的類,它們通常都會有一個非平凡的析構語義。"

函數模板 addressof()

函數 addressof() 返回一個對象的地址。

template <typename T> inline T* addressof(T& v);
template <typename T> inline const T* addressof(const T& v);
template <typename T> inline volatile T* addressof(volatile T& v);
template <typename T> inline const volatile T* addressof(const volatile T& v);

C++ 允許程序員替換單參的 operator&(), 該成員原本是用於獲得對像地址的。要獲得一個對象的真實地址,需要一些醜陋的轉換技巧,以避免調用被重載的 operator&(). 函數 addressof() 為這些所需的代碼提供了一個包裝,使得你可以很容易獲得一個對象的真實地址。

程序 addressof_test.cpp 可用於驗證 addressof() 是否工作正常。

這是由 Brad King based 基於 Doug Gregor 的思路所提供的。

例子

#include <boost/utility.hpp>

struct useless_type {};
class nonaddressable {
useless_type operator&() const;
};

void f() {
nonaddressable x;
nonaddressable* xp = boost::addressof(x);
// nonaddressable* xpe = &x; /* 錯誤的 */
}

類模板 result_of

類模板 result_of 幫助確定一個調用表達式的類型。給定一個類型 F 的左值 f 和類型 T1, T2, ..., TN 的左值 t1, t2, ..., tN ,類型 result_of<F(T1, T2, ..., TN)>::type 定義了表達式 f(t1, t2, ...,tN) 的類型。該實現允許類型 F 是函數指針、函數引用、成員函數指針或類類型。如果 F 是一個類類型,帶有成員類型 result_type, 則 result_of<F(T1, T2, ..., TN)>F::result_type. 否則,result_of<F(T1, T2, ..., TN)>N > 0 時為 F::result<F(T1, T2, ..., TN)>::type,當 N = 0 時為 void. 有關 result_of 的更多信息,請看 C++ Library TR,N1836, 有關動機和設計原理,請看 result_of 提 議書

類模板 result_of 位於頭文件 <boost/utility/result_of.hpp>. 缺省地,N 可以是0到10之間的任意值。要修改上限,請將宏 BOOST_RESULT_OF_NUM_ARGS 定義為 N 的最大值。

result_of 的實現需要類模板偏特化、正確分析函數類型的能力,以及支持 SFINAE. 如果你的編譯器不支持 result_of, 請包含頭文件 boost/utility/result_of.hpp,它將定義宏 BOOST_NO_RESULT_OF. 這是由 Doug Gregor 貢獻的。

支持 Base-from-Member 慣用法的類模板

請看 單獨的文檔

宏 BOOST_BINARY

BOOST_BINARY 用於表示二進制字面值。它接受一個二進制數字作為參數,這個數字由任意個1和0組成,這些1和0被分為若干組,每組的長度為1到8,各組間以空格分隔。決 定所產生字面值的類型的規則與十六進制及八進制字面值的規則相同(2.13.1p1)。通過具體實現,這個宏在預 處理期間被展開為一個八進制字面值,因此它沒有運行期開銷,而且其結果可以在任何一個可以使用八進制字面值的地方使用。

為了直接支持帶有後綴的二進制字面值,我們還提供了形如 BOOST_BINARY_XXX 的宏,其中 XXX 是標準的整數後綴,包括所有大小寫。另外,在提供了 long long 和 unsigned long long 類型的編譯器中,LL 和 ULL 後綴可以用於表示這兩個類型。

BOOST_BINARY 宏族位於頭文件 <boost/utility/binary.hpp> 中,自動由 <boost/utility.hpp> 包含。

由 Matt Calabrese 貢獻。

Example

void foo( int );

void foo( unsigned long );

void bar()
{
int value1 = BOOST_BINARY( 100 111000 01 1 110 );

unsigned long value2 = BOOST_BINARY_UL( 100 001 ); // unsigned long

long long value3 = BOOST_BINARY_LL( 11 000 ); // long long if supported

assert( BOOST_BINARY( 10010 )
& BOOST_BINARY( 11000 )
== BOOST_BINARY( 10000 )
);

foo( BOOST_BINARY( 1010 ) ); // calls the first foo

foo( BOOST_BINARY_LU( 1010 ) ); // calls the second foo
}

Revised  04 September, 2008

c Copyright Beman Dawes 1999-2003.

Distributed under the Boost Software License, Version 1.0. See www.boost.org/LICENSE_1_0.txt