zoukankan      html  css  js  c++  java
  • c++ 11 enable_if

    最近在看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<<"
    ";
            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

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

  • 相关阅读:
    渲染你刚刚上传的图片,再进行二次上传
    详情页需要显示图片
    上传图片
    毛利率保留俩位小数
    去除input的前后的空格
    vue下载模板、导出excle
    如何从一个对象里面拿数据
    登录注册
    ajax发送请求的数据类型
    WampServer修改MySQL密码
  • 原文地址:https://www.cnblogs.com/zhang-wen/p/7358067.html
Copyright © 2011-2022 走看看