2

考慮下面的函數模板:++自動評估戰略選擇用C

template<typename T> void Foo(T) 
{ 
    // ... 
} 

傳遞值語義意義,如果T正好是整數類型,或至少一種類型的便宜複製。 另一方面,如果T碰巧是複製的昂貴類型,則使用pass-by- [const]引用語義更有意義。

讓我們假設你正在寫一個圖書館。理想情況下,作爲一名圖書館實施者,您的工作就是爲您的消費者提供一個既簡潔又高效的乾淨API。那麼如何提供一個通用接口來迎合這兩種參數傳遞策略?


這是我在得到這個第一次嘗試的工作:

#include <boost/type_traits.hpp> 

template<typename T> struct DefaultCondition 
{ 
    enum {value = boost::is_integral<T>::value /* && <other trait(s)> */}; 
}; 

template< typename T, class Condition = DefaultCondition<T> > class Select 
{ 
    template<bool PassByValue = Condition::value, class Dummy = void> struct Resolve 
    { 
    typedef T type; 
    }; 

    template<class Dummy> struct Resolve<false, Dummy> 
    { 
    typedef const T& type; 
    }; 

    public: typedef typename Resolve<>::type type; 
}; 

典型用途:

template<typename T> class EnterpriseyObject 
{ 
    typedef typename Select<T>::type type; 

    public: explicit EnterpriseyObject(type) 
    { 
    // ... 
    } 
}; 

struct CustomType {}; 

void Usage() 
{ 
    EnterpriseyObject<int>(0); // Pass-by-value. 
    (EnterpriseyObject<CustomType>(CustomType())); // Pass-by-const-reference. 
} 

這當然,間接打破隱性模板參數扣除非類模板:

template<typename T> void Foo(typename Select<T>::type) 
{ 
    // ... 
} 

void Usage() 
{ 
    Foo(0);  // Incomplete. 
    Foo<int>(0); // Fine. 
} 

這可以被「固定」與Boost.Typeof庫和宏,一拉WinAPI

#define Foo(Arg) ::Foo<BOOST_TYPEOF((Arg))>((Arg)) 

雖然這僅僅是一個準便攜式黑客。

正如你所看到的,我的一般方法並不是真的令人滿意。


作爲一個業餘愛好者的程序員,我也沒有現實世界的經驗,也沒有得到獲得生產質量的代碼以供參考。我也意識到這可能看起來像是一個不成熟的優化案例,但我真的對以下幾件事情感興趣:

  1. 您或者您是否曾經使用過這種類型的優化?
  2. Boost(或任何其他公共)庫是否已提供類似的功能?
  3. 如果#1或#2的答案是'是' - 那麼如何處理非類模板案例?
  4. 是否有任何明顯的缺陷,我沒有看到這樣的事情?
  5. 最後,這是一個理智的事情嗎?

*未分析。 ;)

+1

會提及http://www.boost.org/doc/libs/1_43_0/doc/html/ref.html – 5ound 2010-07-07 04:25:57

+0

@ 5ound:也有用,謝謝! – chrosph 2010-07-07 04:30:45

回答

2
  1. 是的。每時每刻。我自己使用它。
  2. 是的,請使用Boost.Utility's Call Traits :)

    用法將...

    template <typename T> 
    void foo(boost::call_traits<T>::param_type param) 
    { 
        // Use param 
    } 
    
  3. 就我所知,非類模板是按值傳遞的,除非它更快。由於部分模板專業化,它可以相對容易地定製。

  4. 對不起,沒有真正讀過你所做的,它只是看起來像我幾個月前經歷的。因此,不能真正回答這個問題。我的建議是閱讀Boost.Utility。

  5. 當然!

+0

優秀。張貼之前應該看起來更難。非常感謝! ;) – chrosph 2010-07-07 04:18:35