2014-12-02 2 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() это название двух различных функциональных прототипов, так что не тело, содержащее оператор возврата. Это означает, что он никогда не возвращает значение типа uniform_real_distribution<T>, или uniform_int_distribution<T>.

Так не должно decltype не удается вызвать неполную функцию? Или decltype просто не вызывает функцию вообще и вместо этого просто оценивает тип возврата?

+2

второй вариант: 'decltype' просто * * оценивает тип возвращаемого значения. – Jarod42

+1

'decltype' фактически не вызывает ничего. Все, что он делает, это определить * тип * некоторого выражения, * без фактической оценки выражения. * Он просто смотрит на выражение и спрашивает: «Если бы я это оценил, каким будет тип результата?» Это не зависит от тел каких-либо функций или методов, а только от прототипов. – cdhowie

ответ

5

decltype - неоценимый контекст. Он просто работает на уровне типа, поэтому, зная, что тело dist, где бы оно ни было, возвращает некоторый тип X.

+0

Удивительный! Спасибо за быстрый ответ! – flakes

0

decltype спецификатор проверяет объявленный тип объекта или запрашивает возвращаемый тип выражения, то есть что он делает.

здесь альтернативное использование. для показа, что decltype заботится только о типе любого проходящего выражения

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'; 
} 
Смежные вопросы