天天看點

boost實用工具

一些有用的boost元件

1. noncopyable

允許程式實作一個禁用拷貝的類

class noncopyable
{
protected:
    noncopyable() {}
    ~noncopyable() {}
private:  // emphasize the following members are private
    noncopyable( const noncopyable& );
    noncopyable& operator=( const noncopyable& );
};
           

用法:

#include <boost/core/noncopyable.hpp>

class X: private boost::noncopyable
{
};
           

2.ignore_unused

編寫代碼過程中有時會出現一些暫時用不到但又必須保留的變量,編譯器對此會發出警告,我們可以顯式地忽略這些變量,進而消除這些警告資訊。

#include<boost/core/ignore_unused.hpp>
int func(int x, int y)
{
    int i;
    ignore_unused(x,i);
    return y;
}
           

3. optional

在實際的軟體開發過程中我們經常遇到無效值的情況,如函數不能總是傳回有效值。抛出異常的方法代價高,增加哨兵角色的方法不夠通用。

optional使用“容器”語義,包裝了“可能産生無效值”的對象,實作了“未初始化”的概念,為這種“無效值”的情形提供了一個更好的解決方案。

#include <boost/optional.hpp>

boost::optional<int> getConfigParam(std::string name);  // return either an int or a `not-an-int`

int main()
{
  if (boost::optional<int> oi = getConfigParam("MaxValue")) // did I get a real int?
    runWithMax(*oi);                                        // use my int
  else
    runWithNoMax();
}
           

4. assign

重載指派操作符“+=”,逗号操作符“,”或者括号操作符“()”用簡潔的文法友善地對标準容器指派或者初始化。

  • Function 

    operator+=()

  • Function 

    operator()()

  • Function 

    list_of()

  • Function 

    map_list_of()

  • Function 

    tuple_list_of()

  • Functions 

    repeat()

    repeat_fun()

     and 

    range()

  • Functions 

    ref_list_of()

     and 

    cref_list_of()

  • Functions 

    ptr_push_back(), ptr_push_front()

    ptr_insert()

     and 

    ptr_map_insert()

  • Function 

    ptr_list_of()

5. tribool

 類似于C++中的bool類型,但是基于三态的布爾邏輯:true(真),false(假)和indeterminate(未知)。

#include<boost/logic/tribool.hpp>
#include<boost/logic/tribool_io.hpp>

int main()
{
	tribool tb(true);
	if (tb)  cout << "true" << endl;

	tb = indeterminate;
	cout << tb << endl;
	cout << (tb || true) << endl;
	cout << (tb && false) << endl;
	
	if (tb)   cout << "never reach here" << endl;  //永遠不會成立
	if (!tb)  cout << "never reach here" << endl;  //永遠不會成立
	if (tb == indeterminate)                       //不會成立
		cout << "indeterminate" << endl;
	if (indeterminate(tb))                         //必須使用indeterminate
		cout << "indeterminate" << endl;
}
           

out: true,2,1,0,indeterminate

6. operators

完全實作操作符的重載工作是單調乏味的,而且增加了代碼量,也增加了出錯的可能性,還必須保證這些操作符都實作了正确的語義。

operators允許使用者在自己的類裡僅定義少量操作符,就可友善地自動生成其他操作符重載,而且保證正确的與i實作。

#include<boost/operators.hpp>

template<typename T>
class MyPoint : boost::totally_ordered<MyPoint<T>>,
	            boost::additive<MyPoint<T>>
{
	T x, y, z;
public:
	explicit MyPoint(int a = 0, int b = 0, int c = 0) :x(a), y(b), z(c) {}
	void print() const
	{	cout << x << "," << y << "," << z << endl;	}

public:
	friend bool operator<(const MyPoint& l, const MyPoint& r)
	{
		return (l.x*l.x + l.y*l.y + l.z*l.z) < (r.x*r.x + r.y*r.y + r.z*r.z);
	}
	friend bool operator==(const MyPoint& l, const MyPoint& r)
	{	return l.x == r.x && l.y == r.y && l.z == r.z;	}
	MyPoint& operator+=(const MyPoint& r)
	{
		x += r.x;
		y += r.y;
		z += r.z;
		return *this;
	}
	MyPoint& operator-=(const MyPoint& r)
	{
		x -= r.x;
		y -= r.y;
		z -= r.z;
		return *this;
	}
};

int main()
{
	MyPoint<double> p0, p1(1, 2, 3), p2(3, 0, 5), p3(3, 2, 1);
	cout << (p0 < p1) << endl;
	cout << (p2 >= p3) << endl;
	cout << (p1 != p2) << endl;
	p3 += p2;
	p3.print();
	MyPoint<double> p4 = p1 + p2;
	p4.print();
}
           

7.exception

boost.exception庫針對标準庫中異常類的缺陷進行了強化,提供<<操作符重載,可以向異常傳入任意資料,有助于增加異常的資訊和表達力。

#include<boost/exception/all.hpp>
//自定義異常類
struct my_exception :virtual std::exception, virtual boost::exception
{};
//異常資訊的類型
typedef boost::error_info<struct tag_err_no, int> err_no;
typedef boost::error_info<struct tag_err_str, string> err_str;

int main()
{
	try {
		try
		{
			throw my_exception() << err_no(10);
		}
		catch (my_exception& e)
		{
			cout << *get_error_info<err_no>(e) << endl;  //獲得異常記憶體儲的資訊
			cout << e.what() << endl;
			e << err_str("other info");    //向異常追加資訊
			throw;                         //再次抛出異常
		}
	}
	catch (my_exception& e)
	{
		cout << *get_error_info<err_str>(e) << endl;
	}
}
           

8.uuid

UUID: "Universally Unique Identifier"。不需要有一個中央認證機構就可以建立全球唯一辨別符。沒有構造函數,需要指定生成器。

#include<boost/uuid/uuid.hpp>
#include<boost/uuid/uuid_generators.hpp>
#include<boost/uuid/uuid_io.hpp>
using namespace boost::uuids;
           

9.config

主要提供給Boost庫開發者,将程式的編譯配置分解為三個部分:平台、編譯器和标準庫,幫助他們解決特定平台和編譯器的相容問題。

BOOST_STRINGIZE可以将任意字面量轉換為字元串,隻能用于編譯器,不支援運作時轉換。最常見的用途實在泛型程式設計中将編譯器常數轉換為字元串,在調試或者輸出日志時相當友善。

BOOST_STATIC_CONSTANT 靜态常量類型, 無需擔心編譯器的能力限制,代碼具可移植性,類似普通變量指派:

BOOST_STATIC_CONSTANT(int, v1 = 10);相當于 static const int v1 = 10;

10. utility

包含了若幹很小但有用的工具。

BOOST_BINARY

用于實作簡單的二進制常量顯示,将一組或多組01數字在編譯期間展開成一個八進制數字。每個數字之間需要空格分隔,每組可以容納一個或八個0/1數字。還有BOOST_BINARY_UL,BOOST_BINARY_LL。

BOOST_CURRENT_FUNCTION

獲得包含該宏的外圍函數的名稱,一個包含完整函數聲明的編譯器字元串。在配合抛出異常或者輸出診斷日志時非常有用。

#include<boost/current_function.hpp>

double func()
{
	cout << BOOST_CURRENT_FUNCTION << endl;
	return 0.0;
}

//string str = BOOST_CURRENT_FUNCTION;    //error, 在函數作用域外無意義

int main()
{
	int x = BOOST_BINARY(0110);
	cout << x << endl;

	//cout << str << endl;
	cout << __FUNCTION__ << endl;
	cout << BOOST_CURRENT_FUNCTION << endl;
	func();
}