簡體   English   中英

使用enable_if專門設計模板方法

[英]Specializing a template method with enable_if

我正在編寫一個存儲std::function的模板類,以便稍后調用它。 這是簡化的代碼:

template <typename T>
struct Test
{
    void call(T type)
    {
        function(type);
    }
    std::function<void(T)> function;
};

問題是這個模板不能為void類型編譯,因為

void call(void type)

變得不確定。

專門針對void類型並不能解決問題,因為

template <>
void Test<void>::call(void)
{
    function();
}

仍與call(T Type)聲明call(T Type)不兼容。

因此,使用C ++ 11的新功能,我嘗試了std::enable_if

typename std::enable_if_t<std::is_void_v<T>, void> call()
{
    function();
}

typename std::enable_if_t<!std::is_void_v<T>, void> call(T type)
{
    function(type);
}

但它不能用Visual Studio編譯:

錯誤C2039:'type':不是'std :: enable_if'的成員

你會如何解決這個問題?

專攻全班:

template <>
struct Test<void>
{
    void call()
    {
        function();
    }
    std::function<void()> function;
};

如果您不堅持使用void ,並且您的意圖是實際上能夠使用不帶任何參數的Test ,那么使用variadic模板:

template <typename ...T>
struct Test
{
    void call(T ...type)
    {
        function(type...);
    }
    std::function<void(T...)> function;
};

這樣,您可以擁有任意數量的參數。 如果您想要沒有參數,請使用:

Test<> t;
t.call();

所以這不是你想要的語法,但是不需要專門化,這個解決方案更靈活,因為它支持任意數量的參數。

SFINAE不會(僅)處理類/結構的模板參數。

適用於涉及方法模板參數的模板方法。

所以你必須寫

   template <typename U = T>
   std::enable_if_t<std::is_void<U>::value> call()
    { function(); }

   template <typename U = T>
   std::enable_if_t<!std::is_void<U>::value> call(T type)
    { function(type); } 

或者,如果你想確定UT

   template <typename U = T>
   std::enable_if_t<   std::is_same<U, T>::value
                    && std::is_void<U>::value> call()
    { function(); }

   template <typename U = T>
   std::enable_if_t<std::is_same<U, T>::value
                    && !std::is_void<U>::value> call(T type)
    { function(type); } 

ps: std::enable_if_t是一個類型,因此之前不需要typename

ps2:你標記了C ++ 11,但是你的例子使用的是std::enable_if_t ,即C ++ 14和std::is_void_v ,即C ++ 17

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM