C++的函数、闭包与协程

实现序号生成器

函数(Function)

#include <cassert>

int id_generator(int& base, int step)
{
    int result = *base;
    *base += step;
    return result;
}

int main(int argc, char *argv[])
{
    int odd_base = 1;
    int even_base = 0;    
    assert(id_generator(odd_base, 2) == 1);
    assert(id_generator(odd_base, 2) == 3);
    assert(id_generator(odd_base, 2) == 5);
    assert(id_generator(even_base, 2) == 0);
    assert(id_generator(even_base, 2) == 2);
    assert(id_generator(even_base, 2) == 4);        
    return 0;
}
编译
g++ -g add.cpp -o add

闭包(Closure)

#include <cassert>

int main(int argc, char *argv[])
{
    int base = 1;
    auto id_generator_odd = [=]() mutable { int result = base; base += 2; return result; };
    base = 0;
    auto id_generator_even = [=]() mutable { int result = base; base += 2; return result; };
    assert(id_generator_odd() == 1);
    assert(id_generator_odd() == 3);
    assert(id_generator_odd() == 5);
    assert(id_generator_even() == 0);
    assert(id_generator_even() == 2);
    assert(id_generator_even() == 4);
    assert(base == 0);
    return 0;
}
编译
g++ -g closure.cpp -o closure -std=c++0x

协程(Coroutine)

#include <boost/bind.hpp>
#include <boost/coroutine/all.hpp>

typedef boost::coroutines::coroutine< int(void) > IDGenerator;

void idGenerator(IDGenerator::caller_type& ca, int base, int step)
{
    do{
        ca(base);
        base += step;
    }while(true);
}

int main(int argc, char *argv[])
{
    IDGenerator id_generator_odd(boost::bind(idGenerator, _1, 1, 2));
    IDGenerator id_generator_even(boost::bind(idGenerator, _1, 0, 2));
    assert(id_generator_odd.get() == 1);
    assert(id_generator_odd().get() == 3);
    assert(id_generator_odd().get() == 5);
    assert(id_generator_even.get() == 0);
    assert(id_generator_even().get() == 2);
    assert(id_generator_even().get() == 4);
    return 0;
}
编译
g++ -g coroutine.cpp -lboost_context -o coroutine -std=c++0x

特性比较

函数(Function)

  • 无状态
  • 需要独立定义执行体
  • 调用过程中从头到尾执行体内所有代码
  • 在输入相同的情况下,能够保证输出也相同
  • 没有副作用,多线程安全
  • 要借助外部变量保存状态
  • 调用比较麻烦,需要传入保存状态的参数

闭包(Closure)

  • 有状态,内部直接保存
  • 直接内联定义执行体
  • 调用过程中从头到尾执行体内所有代码
  • 输入相同的情况下,输出可能不同
  • 有副作用,非多线程安全
  • 定义时可以多种方式安全地引用外部变量
  • 调用简单,不需要传入保存状态的参数

协程(Coroutine)

  • 有状态,内部直接保存
  • 需要独立定义执行体
  • 调用过程中直接从上次的运行状态继续运行
  • 输入相同的情况下,输出可能不同
  • 严禁多线程访问
  • 调用简单,不需要传入保存状态的参数

cpp