提升元功能类更高阶函数

时间:2012-04-21 12:35:44

标签: c++ boost functional-programming c++11 boost-mpl

元函数类和占位符与高阶函数之间有什么区别?

2 个答案:

答案 0 :(得分:4)

Boost提供了元功能和更高阶函数的功能,但这些概念并不特定于Boost。

术语“元功能”描述了一种模板元编程技术,用于使用模板特化来允许编译器根据其模板参数在编译时做出决策。

通常,元函数可以看起来像这样

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不同})。如果你不熟悉模板元编程,那么你可能想知道为什么这是有用的 - 而现实是它通常只对编写大量使用模板和编译时决策的库的人有用。 (模板元编程是一个完全不同的范例!)


另一方面,“高阶函数”描述了一种函数式编程技术,它允许您将函数作为函数参数传递。使用标准容器标准<algorithm>库,在标准C ++中表达更容易一些。

例如,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的目的是接受(字符)值并返回该值的大写版本。 std :: transform为str.begin()str.end()之间的每个元素抓取toupper的结果(在这个例子中,结果被放回到str)

标准库中有许多其他高阶函数示例 - std::find_ifstd::sortstd::count_if,仅举几例。 C ++中的高阶函数通常可以接受任何类型的可调用对象,包括函数,lambda或函数对象。
传递的可调用对象通常被称为[i]谓词[/ i](虽然我不完全确定这是否是正确使用术语“谓词”)


Boost占位符是函数式编程的另一个方面,称为 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';
}

有了currying,你可以将字符'Q`“绑定”到greater_equals函数,以便创建一个只接受单个参数的谓词,并表示当它的参数“大于或等于Q”时产生true的谓词”

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

答案 1 :(得分:4)

有关详细说明,请参阅

  1. http://www.artima.com/cppsource/metafunctions.html
  2. http://www.mywikinet.com/mpl/paper/mpl_paper.pdf
  3. 原则上,元功能是:

    • 一个类模板,其中所有参数都是类型
    • 具有可公开访问类型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是这种高阶元函数的一个例子。