2014-12-02 69 views
2

我無法理解使用SFINAE的這段代碼。瞭解SFINAE示例

template <typename T> 
auto dist() -> typename std::enable_if<std::is_integral<T>::value, 
             std::uniform_int_distribution<T>>::type; 

template <typename T> 
auto dist() -> typename std::enable_if<std::is_floating_point<T>::value, 
             std::uniform_real_distribution<T>>::type; 
... 

decltype(dist<float>()) unifDistFloat; 
decltype(dist<int>()) unifDistInt; 

dist()是兩個不同的函數原型的名字,所以含return語句沒有身體。這意味着它永遠不會返回uniform_real_distribution<T>uniform_int_distribution<T>類型的值。

因此不應該decltype嘗試調用不完整的函數失敗?或者decltype只是根本不調用函數,而只是評估返回類型?

+2

第二可能性:'decltype'只是* *評估的返回類型。 – Jarod42 2014-12-02 17:18:21

+1

'decltype'實際上不會調用任何東西。它所做的只是確定某個表達式的*類型*,而沒有實際評估表達式*它只是查看錶達式並詢問「如果我確實評估了這個,那麼結果是什麼類型?」這不取決於任何功能或方法的主體,而僅僅是原型。 – cdhowie 2014-12-02 17:20:05

回答

5

decltype未評估的上下文。它只是在類型級別上運行,所以知道dist的主體,無論它在哪裏,都返回一些類型X就足夠了。

+0

太棒了!感謝您及時的回覆! – flakes 2014-12-02 17:26:32

0

decltype說明符檢查實體的聲明類型或查詢表達式的返回類型,即它做了什麼。

這裏是另一種用法。爲表明decltype僅用於type任何轉瞬即逝表情

template<typename U > 
static typename std::enable_if<std::is_same<U, int>::value, std::uniform_int_distribution <U>>::type 
dist(); // NOTE: no function body 

template<typename U > 
static typename std::enable_if<std::is_same<U, double>::value, std::uniform_real_distribution <U>>::type 
dist() 
{ 
    //return; // NOTE: no return 
} 
decltype(dist<T>()) mUniformDistribution; 

可能是問題,爲什麼編譯器不抱怨DIST()函數的不完整的在乎呢?我不知道這是爲什麼。

演示的例子

template<typename T > 
class Random 
{ 
public: 
    Random(const T& min, const T& max) 
     : mUniformDistribution(min, max) 
    {} 

    T operator()() 
    { 
     return mUniformDistribution(mEngine); 
    } 

private: 
    std::default_random_engine mEngine{ std::random_device()() }; 

    template<typename U > 
    static typename std::enable_if<std::is_same<U, int>::value, std::uniform_int_distribution <U>>::type 
    dist(); // NOTE: no function body 

    template<typename U > 
    static typename std::enable_if<std::is_same<U, double>::value, std::uniform_real_distribution <U>>::type 
    dist() 
    { 
     //return; // NOTE: no return 
    } 
    decltype(dist<T>()) mUniformDistribution; 
}; 

int main() 
{ 
    Random<int> getRandom(0, 9); 
    for (int i = 0; i<9; ++i) 
     std::cout << getRandom() << '\n'; 
}