1. 程式人生 > 其它 >c++11禁止用某個模板的方法 ,結合std::enable_if 實現

c++11禁止用某個模板的方法 ,結合std::enable_if 實現

技術標籤:c/c++/c++11

使用場景:

有多個建構函式,也同時用模板實現了一個可變引數的建構函式,現在想分別呼叫不同的建構函式,但可變引數建構函式不加條件,則所有初始化都會呼叫此可變引數建構函式,這是模板自動匹配原則導致的,因此在某些情況下想禁止此可變引數的建構函式,用其他建構函式,怎麼實現呢?現在模板結合std::enable_if可以實現這樣的需求。

std::enable_if的作用可以網上找相關說明,下面是c++11禁止用某個模板的方法,本例子可以主要對可變引數的模板實現

程式碼實現:

#include <type_traits>
#include <iostream>
#include <memory>

class B {
public:
    B() { //沒有引數的建構函式
        std::cout << "B init 0 param" << std::endl;
    }

    B(std::string ptr) { //1個引數的建構函式
        std::cout << "B init 1 param" << std::endl;
    };

    B(std::string sharedPtr, std::string sharedPtr1) { //2個引數的建構函式
        std::cout << "B init 2 param" << std::endl;
    }

    //3個引數的建構函式
    B(std::string sharedPtr, std::string sharedPtr1, std::string sharedPtr2) {
        std::cout << "B init 3 param string " << std::endl;
    }

    //可變引數的建構函式,只有引數大於3個才用此建構函式,假如不用std::enable_if加條件,則所有初始化都會呼叫此建構函式,模板匹配原則
    template<class... Args, typename std::enable_if<(sizeof...(Args) > 3)>::type...>
    B(Args&&... args) {
        fun1(std::forward<Args>(args)...);
        std::cout << "B init n parm" << std::endl;
    }

    ~B() {
        std::cout << "~B" << std::endl;
    };

    template<class U, class T>
    void fun1(U a, U b, U c, T d) {
        std::cout << "----fun1 template a:" << a << ",d:" << d << std::endl;
        funceb<T>(d);
    }
    
    template <typename F>
    typename std::enable_if<(sizeof(F) > 4)>::type funceb(F a)
    {
        std::cout << "----2222 funceb template a:" << a << std::endl;
    }
 

public:
    std::string a;
};

class D;
class C {
public:
    C(){
        std::cout << "0 C init" << std::endl;
    };

    //可變引數的型別都不一樣的實現方式
    template<class... Args>
    void func(Args&&... args) {
        d_ptr = std::make_shared<D>(std::forward<Args>(args)...);
    }

    ~C() {};

private:
    std::shared_ptr<D> d_ptr;
};

class D {
public:
    D(){
        std::cout << "0 D init" << std::endl;
    };

    D(int a, std::string s, float f) {
        std::cout << "1 D init s:" << s << std::endl;
    };
    ~D() {};
};

int main()
{
    B b0;//用沒有引數的建構函式
    B b("a1" ,"a2");//用只有兩個引數的建構函式
    B b1(100 , 200 , 200, "hello"); //用可變引數的建構函式

    C c;
    c.func(1, "aaaaddddd", 2.0);//可變引數的多種資料型別的方式
}