2014-02-24 49 views
1

我對模板元編程相當陌生,並且一直在研究一些概念 - 但是,我遇到了這個特定片段,我一直被困住了。std :: enable_if作爲構造函數的單個參數

template<class TAG, typename... DATATYPES> 
struct Message { 

    Message (typename std::enable_if<sizeof...(DATATYPES) >= 1>) { 
    } 

    ... (various other constructor declarations here) 

    std::tuple<DATATYPES...> m_data; 
}; 

讀它時,它被啓用默認的構造函數,如果有一個或更多類型的參數,但已經測試過所有我得到的是一個編譯錯誤我承擔了。

我希望在幫助我理解這段代碼時提供任何幫助,因爲我明白enable_if應該做什麼,但在這種情況下,我似乎無法將我的頭圍繞在實際發生的事情上。

編輯:我想這不是一個'我如何達到這個特殊效果?'的問題。並且更多地沿着'這段代碼實際產生了什麼,這與我所理解的原始作者的意圖相匹配嗎?'。

+0

我沒有時間發佈完整的解決方案,但看看http://stackoverflow.com/questions/21901637/class-template-why-cant-i-specializea-a-單一方法爲void類型/ 21904225#21904225,相同的技術可以應用於您的問題,除了使用'IsVoid',而不是使用'IsVoid',您將基於arg類型的數量來定義。 –

+1

作爲一個經驗法則,如果你在一個不是模板的函數中看到'enable_if'(即類模板的成員不計數),那就錯了。 –

回答

4

std::enable_if如果沒有遵循::type,則不正確使用。 std::enable_if<expr>本身是一個相當無用的struct類型。

的有條件啓用默認構造函數的正確道路:

template<class TAG, typename... DATATYPES> 
struct Message { 
private: 
    struct dummy_type {}; 
public: 
    template <typename T = std::tuple<DATATYPES...>> 
    Message(
     typename std::enable_if<std::tuple_size<T>() >= 1, dummy_type>::type 
     = dummy_type{} 
    ) {} 
    //... 
}; 

Live at coliru.

+0

是的,謝謝@jrok。 – aschepler

+0

不幸的是,它不會工作。構造函數本身需要是一個模板。 – jrok

+0

它正在做什麼,如果enable_if條件的計算結果爲true,則創建一個帶有結構arg的(無用)構造函數? – GMemory

1

成員函數簽名是類定義的一部分,需要解決的問題時,類實例化。這意味着編譯器也會嘗試enable_if,並且如果未滿足條件,它會發現它沒有嵌套的type - 硬錯誤。

要使SFINAE正常工作,您需要使構造函數成爲一個模板,並且依賴於模板參數enable_if。例如,請參閱@ acheplers的答案。

在OP中的代碼是一個奇怪的方式來斷言DATATYPE包的大小,這將更清楚地與static_assert完成。或者,也許作者只是不知道如何正確地做SFINAE。

+0

感謝您的見解,非常感謝。我有一種直覺,認爲代碼沒有按照它的意圖去做,但我對於能夠確切地說明的概念缺乏牢固的把握。 – GMemory

+0

不客氣。 – jrok

相關問題