2014-12-02 91 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'; 
}