Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

在名字空間作用域設置策略(Setting Polices at Namespace Scope)

有時,你真正想做的是將所有的特殊函數或分佈類型引入到一個特定的名字空間作用域中, 並且讓它們使用一個特定的策略。有兩個宏來輔助這一點的實現:

BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(Policy)

以及:

BOOST_MATH_DECLARE_DISTRIBUTIONS(Type, Policy)

你可以在任何的特殊函數或分佈類型的頭文件#include後面使用這兩個宏中的任何一個。例如:

#include <boost/math/special_functions/gamma.hpp>

namespace myspace{

using namespace boost::math::policies;

// 定義一個在溢出時不拋出異常的策略:
typedef policy<overflow_error<errno_on_error> > my_policy;

// 定義在這個作用域中的特殊函數使用這個策略:   
BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(my_policy)

}

//
// 現在我們可以使用 myspace::tgamma .
// 它們將會自動地使用"my_policy":
//
double t = myspace::tgamma(30.0); // 在溢出錯誤時不會拋出異常

在這個例子中,使用 BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS 產生的結果是一系列小的內聯前向函數(forwarding function)函數得到定義:

template <class T>
inline T tgamma(T a){ return ::boost::math::tgamma(a, mypolicy()); }

template <class T>
inline T lgamma(T a) ( return ::boost::math::lgamma(a, mypolicy()); }

以及其它的函數。注意儘管對於所有的特殊函數都定義了這些前向函數(forwarding function),然而,除非你包含了這些你所使用的特殊函數的頭文件(或者使用boost/math/special_functions.hpp 來包含所有的類和函數),對於那些前向函數(forwarding function),你將會遇到一個編譯時的錯誤:已經聲明,但是沒有定義。

我們可以對分佈類型進行相同的處理,但這一次我們需要指定使用的浮點類型:

#include <boost/math/distributions/cauchy.hpp>

namespace myspace{

using namespace boost::math::policies;

// 定義一個將要使用的策略,在這種情況下,我們想要所有的分佈
// 的訪問函數都可以編譯, 雖然它們在數學上是未定義的
typedef policy<assert_undefined<false> > my_policy;

BOOST_MATH_DECLARE_DISTRIBUTIONS(double, my_policy)

}

// 現在我們可以使用 myspace::cauchy ,它將會使用
// 策略myspace::mypolicy:
//
// 這可以通過編譯,但是會在運行時產生一個定義域錯誤:
//
void test_cauchy()
{
   try
   {
      double d = mean(myspace::cauchy());
   }
   catch(const std::domain_error& e)
   {
      std::cout << e.what() << std::endl;
   }
}

在這個例子中, BOOST_MATH_DECLARE_DISTRIBUTIONS 的作用是為每一個分佈類型定義一個類似於下面的 typedef :

typedef boost::math::cauchy_distribution<double, my_policy> cauchy;
tyepdef boost::math::gamma_distribution<double, my_policy> gamma;

以及其它的typedef。每個typedef的名字是分佈類型的名字去掉"_distribution" 後綴之後的名字。


PrevUpHomeNext