2015-01-15 5 views
1

В его разговоре Современный шаблон метапрограммирования: сборник Часть I, Уолтер Браун работает над обсуждением взаимодействия enable_if с SFINAE.SFINAE вне разрешения перегрузки?

Приблизительно в 47:40 в разговоре ему задают вопрос, для которого я не могу полностью ответить на его вопрос. Однако суть этого звуков заключается в том, что он говорит, что SFINAE стоит отдельно от разрешения перегрузки и просто используется, как правило, для разрешения перегрузки для функций.

Способ, которым я понимаю его ответ, заключается в том, что он также говорит, что SFINAE имеет другое применение.

Вне разрешения перегрузки, где еще может применяться SFINAE? До тех пор, пока он не услышал свой ответ на этот вопрос, я понял, что его использование было только разрешением .

EDIT: Разговор здесь https://www.youtube.com/watch?v=Am2is2QCvxY

+3

Чтобы включить/отключить частичные специализации шаблона? – dyp

+0

Спасибо за это. Я не думал использовать его для этого. Несознание и частичный заказ любой специализированной специализации. Теперь имеет смысл, я думаю об этом. – qeadz

ответ

1

Вы можете отключить любой шаблон на основе параметров, если сочтут это целесообразным.

Например, можно представить, что матричный класс должен быть создан только с помощью арифметических типов. То есть, мы хотим разрешить матрицы реалов и целых чисел, но не строк, скажем. Вы можете сделать это следующим образом:

#include <type_traits> 

template<typename T, 
     typename = typename std::enable_if<std::is_arithmetic<T>::value>::type> 
class Matrix 
{ 
    // ... 
}; 

Теперь, если пользователь делает Matrix<double> m {} он будет компилировать счастливо, но Matrix<std::string> даст простое сообщение об ошибке, что такой тип не определен. Это может помочь пользователю больше, чем страниц сообщений об ошибках, что некоторые внутренние элементы матричного класса не дали допустимого кода для операндов std::string.

Другой вариант использования - выбор между частичными специализациями шаблонов. Это, возможно, глупый пример, но это может дать вам идею. Предположим, у нас есть шаблон, который принимает два параметра типа и хочет специализироваться на случай, когда оба они относятся к одному типу. Однако, если тип меньше int, специализация (по какой-то неясной причине) хуже первичного шаблона, поэтому мы не хотим этого в этом случае.

#include <iostream> 
#include <type_traits> 

template<typename T1, typename T2> 
struct X 
{ 
    void 
    operator()() 
    { 
    std::cout << "I'm the primary template." << std::endl; 
    } 
}; 

template<typename T> 
struct X<T, typename std::enable_if<(sizeof(T) >= sizeof(int)), T>::type> 
{ 
    void 
    operator()() 
    { 
    std::cout << "I'm the partial specialization." << std::endl; 
    } 
}; 

int 
main() 
{ 
    X<int, float> int_float {}; // primary template 
    X<int, int> int_int {};  // partial specialization 
    X<char, char> char_char {}; // primary template! 
    int_float(); 
    int_int(); 
    char_char(); 
} 

Выход на моей системе:

I'm the primary template. 
I'm the partial specialization. 
I'm the primary template. 
+0

Благодарим вас за полное объяснение (и фрагменты кода!). Как только dyp ответил на мой вопрос в разделе комментариев, мне сразу пришло в голову, как это может быть полезно. – qeadz

Смежные вопросы