美文网首页
c++ 11: enable_if

c++ 11: enable_if

作者: 圣地亚哥_SVIP | 来源:发表于2018-11-23 10:25 被阅读0次

    最近在看ceph rgw的源码, 在其客户端数据处理部分遇到std::enable_if的概念,如下:

    template<typename DecorateeT>
    class DecoratedRestfulclient:***{
    ***
    template <typename T = void,
        typename std::enable_if<
            ! std::is_pointer<DecorateeT>::value, T>::type* = nullptr>
    DerefedDecorateeT& get_decoratee() {
        return decoratee;
    }
    
    template <typename T = void,
        typename std::enable_if<
            std::is_pointer<DecorateeT>::value, T>::type* = nullptr>
    DerefedDecorateeT& get_decoratee() {
        return *decoratee;
    }
    ***
    }
    

    enable_if的作用主要用于模板的匹配,偏特化的一个过程。编译器在类型推导的过程中,会尝试推导所有的重载函数,在此过程在过程中,如果enable_if条件不满足,则会在候选函数集合中剔除此函数。

    如上代码,如果DecorateeT是一个指针类型,则匹配第二个,非指针类型则匹配第一个函数。std::is_pointer判断是否是指针。

    以下是一个测试用例:

    #include<iostream>
    
    
    class AJX{
        int a;
        int j;
    public:
        explicit AJX(int a, int j):a(a),j(j){}
        AJX(const AJX& rhs){
            a = rhs.a;
            j = rhs.j;
        }
        AJX& operator=(const AJX& rhs){
            a = rhs.a;
            j = rhs.j;
            return *this;
        }
        AJX(AJX&& rhs){
            a = rhs.a;
            j = rhs.j;
            rhs.a = 0;
            rhs.j = 0;
        }
        friend std::ostream& operator<<(std::ostream& out, const AJX& rhs){
            out<<"AJX: "<<rhs.a<<" "<<rhs.j<<"\n";
            return out;
        }
        ~AJX(){}
    
    };
    
    template<typename DecorateeT>
    class Decorate{
        DecorateeT decoratee;
        typedef typename std::remove_pointer<DecorateeT>::type DerefedDecorateeT;
    public:
        template <typename T = void,typename std::enable_if<! std::is_pointer<DecorateeT>::value, T>::type* = nullptr>
        DerefedDecorateeT& get_decoratee() {
            std::cout<<"Call ref"<<std::endl;
            return decoratee;
        }
        template <typename T = void, typename std::enable_if<std::is_pointer<DecorateeT>::value, T>::type* = nullptr>
        DerefedDecorateeT& get_decoratee() {
            std::cout<<"Call pointer"<<std::endl;
            return *decoratee;
        }
        Decorate(DecorateeT&& decoratee)
        : decoratee(std::forward<DecorateeT>(decoratee)) {
        }
        Decorate()=delete;
        Decorate& operator=(Decorate& decorate){
            decoratee(std::forward<DecorateeT>(decorate.decoratee));
            return *this;
        }
        ~Decorate(){}
    
    };
    
    template<typename T>
    Decorate<T> add_decorate(T&& t){
        return Decorate<T>(std::forward<T>(t));
    }
    
    int main(int args, char* argv[]){
        AJX test(2,3);
        auto tt = add_decorate(&test);
        std::cout<<tt.get_decoratee()<<std::endl;
        auto ts = add_decorate(std::move(test));
        std::cout<<ts.get_decoratee()<<std::endl;
    }
    

    输出如下:

    [root@localhost cpp_test]# ./test_enable 
    Call pointer
    AJX: 2 3
    
    Call ref
    AJX: 2 3
    

    可以看出其根据不同的参数类型调用了不同的模板函数。

    相关文章

      网友评论

          本文标题:c++ 11: enable_if

          本文链接:https://www.haomeiwen.com/subject/bmgdqqtx.html