Отправить ответ rabbitmq на веб-страницу

Мне нравится использовать SFINAE для проверки булевых условий.

template<int I> void div(char(*)[I % 2 == 0] = 0) {
    /* this is taken when I is even */
}

template<int I> void div(char(*)[I % 2 == 1] = 0) {
    /* this is taken when I is odd */
}

Это может быть весьма полезно. Например, я использовал его для проверки того, что список инициализаторов, собранный с использованием служебной запятой, не больше фиксированного размера

template<int N>
struct Vector {
    template<int M> 
    Vector(MyInitList<M> const& i, char(*)[M <= N] = 0) { /* ... */ }
}

Список принимается только в том случае, когда M меньше N, а это означает, что инициализатор списка не слишком много элементов.

Синтаксис char(*)[C] означает: Указатель на массив с типом элемента char и размером C. Если C false (0 здесь), мы получаем недопустимый тип char(*)[0], указатель на массив нулевого размера: SFINAE делает его таким, чтобы затем шаблон игнорировался.

Выражено с boost::enable_if, это выглядит так

template<int N>
struct Vector {
    template<int M> 
    Vector(MyInitList<M> const& i, 
           typename enable_if_c<(M <= N)>::type* = 0) { /* ... */ }
}

На практике я часто нахожу способность проверять условия на полезную способность.

0
задан jamiedanq 18 January 2019 в 14:46
поделиться