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<<"\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

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

 

posted @ 2017-08-14 15:25  舒克_贝塔  阅读(3137)  评论(0编辑  收藏  举报