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

可以看出其根據不同的參數類型調用了不同的模板函數。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM