九九热这里直有精品,1区二区三区在线播放,玖玖爱在线观看资源,国产aⅴ综合网,午夜福利男女,日本亚洲欧美三级,日韩无码黄色导航,内射少妇13区,中文字幕高清网

您身邊的軟件定制專(zhuān)家--9年開(kāi)發(fā)經(jīng)驗(yàn)為您護(hù)航

18678812288
0531-88887250

c++11 function_typetraits備忘

文章作者:濟(jì)南軟件開(kāi)發(fā) 時(shí)間:2016年12月20日

獲取函數(shù)或成員函數(shù)的返回類(lèi)型,參數(shù)類(lèi)型,參數(shù)長(zhǎng)度,類(lèi)類(lèi)型。

 

函數(shù)參數(shù)列表推斷基于typelist:http://www.cnblogs.com/flytrace/p/3551414.html

 

先看一個(gè)普通函數(shù)非const的特化:

 

復(fù)制代碼

    template<typename R, typename... Args>

    struct function_traits<R (Args...)>

    {

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };

復(fù)制代碼

 使用:

 

復(fù)制代碼

int testfunc1(char) { return 1; }

 

int main()

{

    bool b;

    b = std::is_same< typename function_traits<int(double)>::return_type, int>::value;

    std::cout << "is same: " << b << std::endl;

 

    b = std::is_same< typename function_traits<decltype(testfunc1)>::arg<0>::type, char>::value;

    std::cout << "is same: " << b << std::endl;

 

}

復(fù)制代碼

對(duì)于各種參數(shù)類(lèi)型的普通函數(shù),都能正確推斷。但重載函數(shù)的情形需要我們考慮。如下我們?cè)黾觮estfunc1的重載版本:

 

bool testfunc1(double, char) { return false; }

此時(shí)decltype(testfunc1)是無(wú)法編譯通過(guò)的。這并不是我們的function_traits有問(wèn)題。而是在沒(méi)信息的情況下,decltype是無(wú)法選擇testfunc1的重載版本的。除非我們?cè)趂unction_traits顯式特化。

 

函數(shù)指針的function_traits也會(huì)遇到重載問(wèn)題,如下是針對(duì)函數(shù)指針的function_traits:

 

復(fù)制代碼

    template<typename R, typename... Args>

    struct function_traits<R (*)(Args...)>

    {

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };

復(fù)制代碼

decltye(&testfunc1)也是無(wú)法編譯通過(guò)的。很顯然,你自己作為編譯器作者的話,若是沒(méi)有額外的信息,讓你使用decltype去推斷一個(gè)可重載的函數(shù)類(lèi)型,你怎么能夠知道用戶(hù)希望得到哪個(gè)類(lèi)型?除了顯示特化以提供給編譯器信息外,對(duì)于函數(shù)指針,我們還可以提前轉(zhuǎn)換,顯式給以類(lèi)型信息供編譯器推斷,如下:

 

int (*castfunc)(char) = &testfunc1;

b = std::is_same< typename function_traits<decltype(castfunc)>::arg<0>::type, char>::value;

std::cout << "is same: " << b << std::endl;

castfunc1在定義時(shí)得到了testfunc1正確的重載類(lèi)型,因此decltype在推斷castfunc時(shí)就有了信息來(lái)選擇正確的類(lèi)型。

 

這并不是一個(gè)程序技術(shù)問(wèn)題,更算是一個(gè)邏輯問(wèn)題,就好像面對(duì)有多個(gè)定義的單詞,沒(méi)有上下文你是無(wú)法知道它要代表什么意思的。

 

這種顯示轉(zhuǎn)換并不會(huì)帶給我們太多困擾。因?yàn)槭褂胒unction_traits的場(chǎng)景,基本上是一種延遲推斷手段。比如得到消息后,使用泛型手法分發(fā)消息處理。而消息處理函數(shù)我們?cè)谧?cè)的時(shí)候肯定是知道函數(shù)類(lèi)型的,在注冊(cè)時(shí)我們就已經(jīng)可以顯示轉(zhuǎn)換這個(gè)函數(shù)指針而不會(huì)遇到重載問(wèn)題了。直接使用decltype(testfunc1)好像在我們測(cè)試function_traits時(shí)才會(huì)遇到,嗯,另一個(gè)人也遇到了,不然我不會(huì)試驗(yàn)。。。

 

然而確實(shí)存在一個(gè)可能,使我們可以傳入testfunc1,而不用給予完整類(lèi)型信息,雖然不適用于function_traits的情況。如下:

 

http://stackoverflow.com/questions/9054703/overloaded-function-as-argument-of-variadic-template-function

 

復(fù)制代碼

    template<typename ...Args>

    struct OverloadResolved

    {

            template<typename R>

            static auto static_doit( R (*f) (Args...), Args ... args ) -> R { return f(args...);}

    };

 

    template<typename ...Args>

    auto deduce(Args...) -> OverloadResolved<Args...> { return OverloadResolved<Args...>(); }

 

    template<typename T>

    struct dummy : public T { };

 

    #define doit(f, ...) ( dummy<decltype(deduce( __VA_ARGS__ ))> :: static_doit(f, __VA_ARGS__) )

復(fù)制代碼

使用:

 

char aa = 'a'; double ff = 0.1;

std::cout << doit(testfunc1, aa) << "   " << doit(testfunc1, ff, aa) << std::endl;

可以看到,雖然testfunc1有2個(gè)重載版本,但仍能正確的執(zhí)行testfunc1(aa)和testfunc1(ff, aa).

 

當(dāng)然因?yàn)榇颂幗o出了參數(shù)信息。這是一個(gè)運(yùn)行時(shí)方案,而function_traits要求我們?cè)诰幾g期就推斷。

 

以下添加類(lèi)成員函數(shù)的function_traits:

 

復(fù)制代碼

template <typename R, typename T, typename... Args>

    struct function_traits<R (T::*)(Args...)>

    {

        typedef T class_type;

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };

復(fù)制代碼

還需要添加const,volatile修飾符的。以下是更完整的版本:

 

    template<typename T>

    struct function_traits;

 

    template<typename R, typename... Args>

    struct function_traits<R (Args...)>

    {

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };

 

    template<typename R, typename... Args>

    struct function_traits<R (Args...) const>

    {

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };

 

    template<typename R, typename... Args>

    struct function_traits<R (Args...) volatile>

    {

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };

 

    template<typename R, typename... Args>

    struct function_traits<R (Args...) const volatile>

    {

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };

 

    template<typename R, typename... Args>

    struct function_traits<R (*)(Args...)>

    {

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };

 

 

 

 

    template <typename R, typename T, typename... Args>

    struct function_traits<R (T::*)(Args...)>

    {

        typedef T class_type;

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };

 

 

    template <typename R, typename T, typename... Args>

    struct function_traits<R (T::*)(Args...) const>

    {

        typedef T class_type;

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };

 

    template <typename R, typename T, typename... Args>

    struct function_traits<R (T::*)(Args...) volatile>

    {

        typedef T class_type;

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };

 

    template <typename R, typename T, typename... Args>

    struct function_traits<R (T::*)(Args...) const volatile>

    {

        typedef T class_type;

        typedef R return_type;

        typedef typelist<Args...> arglist;

        enum { arg_count = sizeof...(Args) };

        template<unsigned int N>

        struct arg

        {

            typedef typename at<N, arglist>::type type;

        };

    };


想要了解更多詳情歡迎來(lái)電咨詢(xún)18678812288
登陸網(wǎng)址:m.h6244.cn。
聯(lián)系人:王經(jīng)理。

凤凰县| 恩平市| 荆州市| 南木林县| 翼城县| 赤峰市| 仙游县| 甘肃省| 辽中县| 朝阳区| 乌拉特前旗| 宽城| 明水县| 西城区| 德江县| 黄山市| 南乐县| 加查县| 茌平县| 绿春县| 揭阳市| 鸡东县| 龙胜| 小金县| 岳池县| 平罗县| 军事| 张北县| 定边县| 北宁市| 全南县| 鄯善县| 永丰县| 兴文县| 五大连池市| 荔波县| 揭东县| 承德县| 桂东县| 安阳市| 阳原县|