2012-04-21 3 views

ответ

4

Boost предоставляет функции для функций Metafunctions и более высокого порядка, но концепции не являются специфическими для Boost.

термин «metafunction» описывает метод метапрограммирования шаблонов для использования специализированной специализации, позволяющий компилятору принимать решения во время компиляции в зависимости от аргумента шаблона.

Обычно metafunction может выглядеть примерно так

template<bool B> 
struct my_metafunction 
{ 
    enum { value = 1 }; 
}; 

template<> 
struct my_metafunction<false> 
{ 
    enum { value = 0 }; 
}; 

Когда my_metafunction используется, точное значение my_metafunction<B>::value будет зависеть от величины B (т.е. my_metafunction<true>::value будет отличаться от my_metafunction<false>::value) , Если вы не знакомы с метапрограммированием шаблонов, то вам, вероятно, интересно , почему это полезно - и на самом деле это полезно только тем людям, которые пишут библиотеки, которые в значительной степени используют шаблоны и принятие решений во время компиляции. (Шаблон метапрограммирование это совершенно другая парадигма!)


с другой стороны, «функции высшего порядка» описывает функциональную технику программирования, которая позволяет передавать функции в качестве аргументов функции. Это немного проще выразить в стандартном C++ со стандартной библиотекой <algorithm>, работающей со стандартными контейнерами. Например, C++ включает функцию более высокого порядка, называемую transform, ее целью является прохождение каждого элемента в контейнере (например, вектор, строка, список, карта, массив и т. Д.) И выполнение преобразования для каждого элемент.

std::string str = "Hello, World"; 
std::transform(str.begin(), 
       str.end(), 
       str.begin(), 
       std::toupper); // Note - toupper is a function! 

std::cout << str << std::endl; 

Преобразование выполняется зависит от его конечного параметра, std::toupper. целью std :: toupper является принятие значения (символа) и возврат версии в верхнем регистре этого значения. станд :: преобразование захватывает результат из ToUpper для каждого элемента между str.begin() и str.end() (и в этом примере, результат получает положить обратно в ул)

Есть много других примеров функций высшего порядка в стандартной библиотеке - std::find_if, std::sort, std::count_if, чтобы назвать несколько. Функции более высокого порядка в C++ обычно могут принимать любые вызываемые объекты, включая функцию, лямбда или объект функции.
отзывной объекты, которые передаются часто называют [I] предикатами [/ i] (хотя я не совсем уверен, что это правильное использование термина «предикат»)


подпиточного заполнители являются частью другого аспекта функционального программирования, известного как currying - который позволяет вам связывать параметры с функцией до вызова этой функции. (в мире Boost результат currying - это функция-объект, который обычно передается функции более высокого порядка).

Currying предназначен как альтернатива написанию собственного специализированного вызываемого объекта путем повторного использования существующих вызываемых объектов/предикатов и установки некоторых из их аргументов в бетоне до их использования.

Например, вы можете использовать функцию более высокого порядка find_if для поиска строки для первого символа, которая больше «q». стандартная библиотека C++ включает вызываемый объект с именем greater_equals, за исключением того, что ему нужен второй параметр, который будет использоваться find_if («Больше, чем и равно ** на что?»)

Без currying вы можете написать функцию (игнорировать все чувствительность к регистру в настоящее время), такие как

bool greater_than_or_equals_to_q(char c) 
{ 
    return c >= 'Q'; 
} 

с выделки, вы могли бы «привязать» характер «Q` функции greater_equals для того, чтобы создать предикат, который принимает только один аргумент, и представляет собой предикат давая истину, когда ее аргумент «больше или равен Q».

std::bind(std::greater_equal<char>(), 
      std::placeholders::_1, 
      'Q'); 

Таким образом, используя заглавную строку:

std::string str = "HELLO WORLD"; 
auto gt_eq_Q = std::bind(std::greater_equal<char>(), 
          std::placeholders::_1, 
          'Q'); 

auto iter = std::find_if(str.begin(), str.end(), gt_eq_Q); 
std::cout << *iter << std::endl; 

Выход, как и ожидалось - первый символ в «привет мир», который больше, чем или равный к «Q» происходит быть 'W'

W 
+0

Возможно, неправильные заполнители, о которых OP хочет узнать. Boost.MPL имеет метафайлы более высокого порядка (хотя OP действительно упоминал функции), например 'less <_1, _2>'. [Соответствующие документы] (http://www.boost.org/doc/libs/1_49_0/libs/mpl/doc/tutorial/tutorial-metafunctions.html). –

+2

«Предикат» - это функция, которая оценивает условие на каком-либо объекте (или объектах), возвращая, является ли условие истинным или нет. Таким образом, для функций более высокого порядка достаточно использовать функции предиката в качестве аргументов (например, функция фильтра, возвращающая все элементы коллекции, которые удовлетворяют некоторому условию, принимает функцию для проверки условия, поэтому вам не нужно переписывать фильтр для всех возможных условий). Таким образом, предикат - это в основном особый * вид * вещи, которую вы передаете функции более высокого порядка; неверно всегда называть их предикатами. – Ben

4

подробные объяснения посмотреть на

  1. http://www.artima.com/cppsource/metafunctions.html
  2. http://www.mywikinet.com/mpl/paper/mpl_paper.pdf

В принципе metafunction либо:

  • шаблон класса, в котором все параметры типа
  • класс с общедоступного типа type

Например:

template <bool, class L, class R> 
struct IF 
{ 
    typedef R type; 
}; 

template <class L, class R> 
struct IF<true, L, R> 
{ 
    typedef L type; 
}; 

Функция, которая работает с другой функцией, известна как функция более высокого порядка. Таким образом, метафункция более высокого порядка является метафоном, который принимает другие метафундации в качестве параметров и использует их при вычислении. Это концептуально похоже на функцию, принимающую указатель на другую функцию или объект функции как параметр во время выполнения. Единственное отличие состоит в том, что метафункции существуют только во время компиляции. boost::mpl::transform - пример такой метафоры более высокого порядка.

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