Boost C++ Libraries Home Libraries People FAQ More

PrevUpHomeNext

為基於特定基礎的特殊函數改變策略(Changing the Policy on an Ad Hoc Basis for the Special Functions)

這個庫中的所有的特殊函數都以兩種重載的形式出現,一個具有最後的「策略」參數,一個沒有最後的「策略」參數。例如:

namespace boost{ namespace math{

template <class RealType, class Policy>
RealType tgamma(RealType, const Policy&);

template <class RealType>
RealType tgamma(RealType);

}} // namespaces

通常,第二種形式是第一種形式的前向包裝(forwarding wrapper),類似於下面:

template <class RealType> inline RealType tgamma(RealType x) { return tgamma(x, policies::policy<>()); }

因此調用一個使用特定策略的特殊函數實際上是定義需要使用的策略類型並將其傳遞給最後一個參數。例如,假設我們希望函數tgamma 以一種C兼容( C-compatible )的方式工作,並在遇到錯誤時設置 set ::errno 而永遠都不會拋出一個異常:

#include <boost/math/special_functions/gamma.hpp>
//
//定義將要使用的策略:
//
using namespace boost::math::policies;
typedef policy<
   domain_error<errno_on_error>,
   pole_error<errno_on_error>,
   overflow_error<errno_on_error>,
   evaluation_error<errno_on_error> 
> c_policy;
//
// 當調用函數tgamma時使用這個策略:
//
int main()
{
   errno = 0;
   std::cout << "Result of tgamma(30000) is: " 
      << boost::math::tgamma(30000, c_policy()) << std::endl;
   std::cout << "errno = " << errno << std::endl;
   std::cout << "Result of tgamma(-10) is: " 
      << boost::math::tgamma(-10, c_policy()) << std::endl;
   std::cout << "errno = " << errno << std::endl;
}

輸出結果為:

Result of tgamma(30000) is: 1.#INF
errno = 34
Result of tgamma(-10) is: 1.#QNAN
errno = 33

另一方面,對於特殊的使用,我們可以使用make_policy 輔助函數(helper function)來為我們生成一個策略:這種使用很冗長(verbose),所以可能一個策略只會使用一次時才會使用這種方法:

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

int main()
{
   using namespace boost::math::policies;
   errno = 0;
   std::cout << "Result of tgamma(30000) is: " 
      << boost::math::tgamma(
         30000, 
         make_policy(
            domain_error<errno_on_error>(),
            pole_error<errno_on_error>(),
            overflow_error<errno_on_error>(),
            evaluation_error<errno_on_error>() 
         )
      ) << std::endl;
   // 檢查 errno 已被設置:
   std::cout << "errno = " << errno << std::endl;
   // 在一個 pole 處計算:
   std::cout << "Result of tgamma(-10) is: " 
      << boost::math::tgamma(
         -10, 
         make_policy(
            domain_error<errno_on_error>(),
            pole_error<errno_on_error>(),
            overflow_error<errno_on_error>(),
            evaluation_error<errno_on_error>() 
         )
      ) << std::endl;
   // 檢查 errno 已被設置:
   std::cout << "errno = " << errno << std::endl;
}


PrevUpHomeNext