2012-07-06 54 views
1

我有一個模板類,某些成員函數只有在模板參數滿足某些條件時纔有意義。例如,使用std::enable_if<>我只能爲這些情況定義它們,但我怎樣纔能有條件地調用它們?下面是一個簡單的例子C++編譯時條件成員函數調用

template<class T> class A 
{ 
    typename std::enable_if<std::is_floating_point<T>::value>::type a_member(); 
    void another_member() 
    { 
    a_member(); // how to restrict this to allowed cases only? 
    } 
}; 
+0

你想在編譯時刪除它們嗎,編譯時出錯,還是在運行時知道? – Linuxios 2012-07-06 14:14:15

+0

如何爲其餘類型(而不是浮點)提供一個空的a_member重載。 – mfontanini 2012-07-06 14:14:31

+0

@Linuxios只是在編譯時不會在運行時調用它們。 – Walter 2012-07-06 14:17:39

回答

7

首先,你不能像使用SFINAE - 模板類型參數需要的功能,而不是類。

完整的解決方案是這樣的:

template<class T> class A 
{ 
private: 
    template <class S> 
    typename std::enable_if<std::is_floating_point<S>::value>::type a_member() { 
     std::cout << "Doing something"; 
    } 

    template <class S> 
    typename std::enable_if<!std::is_floating_point<S>::value>::type a_member() { 
     //doing nothing 
    } 

public: 
    void another_member() 
    { 
    a_member<T>(); 
    } 
}; 


int main() { 
    A<int> AInt; 
    AInt.another_member();//doesn't print anything 

    A<float> AFloat; 
    AFloat.another_member();//prints "Doing something" 
} 
+0

+1太棒了!我嘗試過,但沒有S上的附加模板,這對避免功能過載至關重要。 – Walter 2012-07-06 14:30:18

+1

額外的模板參數不是爲了避免模糊的重載。 SFINAE僅適用於功能模板,不適用於類模板,因此您需要製作這些功能模板。 – 2012-07-06 14:41:23

+0

這是語義。爲了使用SFINAE,需要不同的函數簽名,並且模糊的重載不能給出(我的編譯器(gcc/4.7.0)抱怨超載)。 – Walter 2012-07-06 16:34:48

1

警告:這是一個可能永遠不會工作,我沒有嘗試過一個完整的,可怕的黑客。

嘗試增加這類聲明:

typename std::enable_if<std::is_floating_point<T>, int*>::type a_enabled_p() { return 0;}; 
void another() 
{ 
    if((a_enabled_p()+1)==1) 
    { 
    //Not enabled 
    } 
    else if((a_enabled_p()+1)==sizeof(int)) 
    { 
    //Is enabled 
    } 
} 

這也是爲什麼這個恐怖可能工作。如果它們是浮點數,謂詞的返回值是int*。如果他們是,沒有typedef,它默認爲int(我希望)。當您將1加到int*時,您確實會添加sizeof(int)。將int加1加1。這意味着通過檢查添加一個的值,我們知道。

注意:不要使用它。這很有趣,拿出,但上述的答案是非常非常

MUCH

更好。不要使用這個。請。

+0

這是一個運行時版本,不會編譯(您的「未啓用」代碼只能被調用,但仍然可用)。 – Walter 2012-07-06 14:27:25

+0

@Walter:我從來沒有說過它會工作,但爲什麼?怎麼樣?這是我第一次見到'std :: enable_if',所以請賜教。 – Linuxios 2012-07-06 14:30:04

+2

看起來很酷;我想我會用這個 – 2014-02-05 09:48:05