(3)boost采用的辦法也是C++98的辦法,就是為不同參數(shù)個數(shù)的Signature進(jìn)行特化:
template
class function
{
R operator()(T1 a1);
};
template
class function
{
R operator()(T1 a1, T2 a2);
};
template
class function
{
R operator()(T1 a1, T2 a2, T3 a3);
};
… // 再寫下去頁寬不夠了,打住…
如此一共N(N由一個宏控制)個版本。
這種做法有兩個問題:一,函數(shù)的參數(shù)個數(shù)始終還是受限的,你作出N個特化版本,那么對N+1個參數(shù)的函數(shù)就沒轍了。boost::tuple也是這個問題。二,代碼重復(fù)。每個特化版本里面除了參數(shù)個數(shù)不同之外基本其它都是相同的;boost解決這個問題的辦法是利用宏,宏本身的一大堆問題就不說了,你只要打開boost.function的主體實現(xiàn)代碼就知道有多糟糕了,近一千行代碼,其中涉及元編程和宏技巧無數(shù),可讀性可以說基本為0。好在這是個標(biāo)準(zhǔn)庫(boost.function將加入tr1)不用你維護(hù),如果是你自己寫了用的庫,恐怕除了你誰也別想動了。所以第二個問題其實就是可讀性可維護(hù)性問題,用Matthew Wilson的說法就是可發(fā)現(xiàn)性和透明性的問題,這是一個很嚴(yán)重的問題,許多C++現(xiàn)代庫因為這個問題而遭到詬病。
現(xiàn)在,讓我們來看一看加入了variadic templates之后的C++09實現(xiàn):
template
struct invoker_base {
virtual R invoke(Args...) = 0;
virtual ~invoker_base() { }
};
template
struct functor_invoker : public invoker_base
{
explicit functor_invoker(F f) : f(f) { }
R invoke(Args... args) { return f(args...); }
private:
F f;
};
template
class function;
template
class function
{
public:
template
function(F f) : invoker(0)
{
invoker = new functor_invoker(f);
}
R operator()(Args... args) const
{
return invoker->invoke(args...);
}
private:
invoker_base* invoker;
};
template
class function
{
R operator()(T1 a1);
};
template
class function
{
R operator()(T1 a1, T2 a2);
};
template
class function
{
R operator()(T1 a1, T2 a2, T3 a3);
};
… // 再寫下去頁寬不夠了,打住…
如此一共N(N由一個宏控制)個版本。
這種做法有兩個問題:一,函數(shù)的參數(shù)個數(shù)始終還是受限的,你作出N個特化版本,那么對N+1個參數(shù)的函數(shù)就沒轍了。boost::tuple也是這個問題。二,代碼重復(fù)。每個特化版本里面除了參數(shù)個數(shù)不同之外基本其它都是相同的;boost解決這個問題的辦法是利用宏,宏本身的一大堆問題就不說了,你只要打開boost.function的主體實現(xiàn)代碼就知道有多糟糕了,近一千行代碼,其中涉及元編程和宏技巧無數(shù),可讀性可以說基本為0。好在這是個標(biāo)準(zhǔn)庫(boost.function將加入tr1)不用你維護(hù),如果是你自己寫了用的庫,恐怕除了你誰也別想動了。所以第二個問題其實就是可讀性可維護(hù)性問題,用Matthew Wilson的說法就是可發(fā)現(xiàn)性和透明性的問題,這是一個很嚴(yán)重的問題,許多C++現(xiàn)代庫因為這個問題而遭到詬病。
現(xiàn)在,讓我們來看一看加入了variadic templates之后的C++09實現(xiàn):
template
struct invoker_base {
virtual R invoke(Args...) = 0;
virtual ~invoker_base() { }
};
template
struct functor_invoker : public invoker_base
{
explicit functor_invoker(F f) : f(f) { }
R invoke(Args... args) { return f(args...); }
private:
F f;
};
template
class function;
template
class function
{
public:
template
function(F f) : invoker(0)
{
invoker = new functor_invoker(f);
}
R operator()(Args... args) const
{
return invoker->invoke(args...);
}
private:
invoker_base* invoker;
};