2011-06-01 32 views
7

如何檢測返回類型和空值和一元函數指針,std :: function對象以及函數(包括lambdas)的參數類型?檢測函數對象(仿函數)和lambda特徵

Boost的function_traitsfunctional traits並不完全讓我開箱,但我願意補充或替換它們。

我可以做這樣的事情:

namespace nsDetail 
{ 
    class Dummy { Dummy(); }; 
} 

template<class Fn> struct FnTraits; 

template<class R> 
struct FnTraits<R(*)()> 
{ 
    typedef nsDetail::Dummy ParamType; 
    typedef R    ReturnType; 
    typedef R Signature(); 
}; 

template<class R, class P> 
struct FnTraits<R(*)(P)> 
{ 
    typedef P ParamType; 
    typedef R ReturnType; 
    typedef R Signature(P); 
}; 

template<class R> 
struct FnTraits< std::function<R()> > 
{ 
    typedef nsDetail::Dummy ParamType; 
    typedef R    ReturnType; 
    typedef R Signature(); 
}; 

template<class R, class P> 
struct FnTraits< std::function<R(P)> > 
{ 
    typedef P ParamType; 
    typedef R ReturnType; 
    typedef R Signature(P); 
}; 

但我應該如何爲專門仿函數/ lambda表達式?

更新:也許類似this answer to a different question,但從重載翻譯到專業化?

回答

6

這是不可能在仿函數一般情況下,即使用operator()類類型。這也包括lambda對象。考慮這樣operator()過載的情況下:

struct functor { 
    double 
    operator()(double) const; 

    int 
    operator()(int) const; 
}; 

typedef function_traits<functor>::result_type result_type; 

我應該result_type是什麼?

。注意,作爲一種解決方法,一些協議(例如,從boost::apply_visitor Boost.Variant)要求一個result_type存在於類,條件是所有的過載,同時接受不同類型,所有返回與此兼容的類型的假設result_type

當然給出了一些類型T0 ... Tn,std::result_of<functor(T0, ..., Tn)>::type給出了與參數類型關聯的返回類型。


在的operator()正好一個過載是本[1],可以採取operator()構件並檢查該案件。

struct not_overloaded { 
    double 
    operator()(double) const; 
}; 

template<typename T> 
struct functor_traits { 
    typedef decltype(&T::operator()) type; 
}; 

functor_traits<not_overloaded>::type具有類型double (not_overloaded::*)(double) const這裏,並與剛剛有點努力,你可以從這個提取你想要什麼。 (例如形式Ret (T::*)(Args...) const的特殊化將匹配類型。)

[1]:但是算符可通過隱式轉換爲一個函數指針/參考,也因此你可能會錯過

+0

在這個答案是什麼東西:http://stackoverflow.com/questions/4170201/c0x-overloading-on-lambda-arity/4196447#4196447它使用重載,但也許類似的東西可以用於專業化? – metal 2011-06-01 13:59:52

+1

@mlimber我確實編輯了我的答案以反映 – 2011-06-01 14:05:57

+0

謝謝! – metal 2011-06-01 14:08:05