官术网_书友最值得收藏!

Functional programming associated with C++

Functional programming is another addition to C++ that provides the user with compiler assistance, in the form of lambda functions. Currently, this must be carried out by hand in C.

In C, a functional programming construct can be achieved using a callback. For example, consider the following code:

void
guard(void (*ptr)(int *val), int *val)
{
lock();
ptr(val);
unlock();
}

void
inc(int *val)
{
*val++;
}

void
dec(int *val)
{
*val--;
}

void
foo()
{
int count = 0;
guard(inc, &count);
guard(dec, &count);
}

In the preceding code example, we create a guard function that locks a mutex, calls a function that operates on a value, and then unlocks the mutex on exit. We then create two functions, one that increments a value given to it, and one that decrements a value given to it. Finally, we create a function that instantiates a count, and then increments the count and decrements the count using the guard function.

There are a couple of issues with this code:

  • The first issue is the need for pointer logic to ensure we can manipulate the variable we wish to operate on. We are also required to manually pass this pointer around to keep track of it. This makes the APIs clunky, as we have a lot of extra code that we have to write manually for such a simple example. 
  • The function signature of the helper functions is static. The guard function is a simple one. It locks a mutex, calls a function, and then unlocks it. The problem is that, since the parameters of the function must be known while writing the code instead of at compile time, we cannot reuse this function for other tasks. We will need to hand-write the same function for each function signature type we plan to support. 

The same example can be written using C++ as follows:

template<typename FUNC>
guard(FUNC f)
{
lock();
f();
unlock();
}

void
foo()
{
int count = 0;
guard(inc, [&]{ count++ });
guard(inc, [&]{ count-- });
}

In the preceding example, the same functionality is provided, but without the need for pointers. In addition, the guard function is generic and can be used for more than one case. This is accomplished by leveraging both template programming and functional programming.

The lambda provides the callback, but the parameters of the callback are encoded into the lambda's function signature, which is absorbed by the use of a template function. The compiler is capable of generating a version of the guard function for use that takes the parameters (in this case, a reference to the count variable) and storing it in the code itself, removing the need for users to do this by hand. 

The preceding example will be used a lot in this book, especially when creating benchmarking examples, as this pattern gives you the ability to wrap functionality in code designed to time the execution of your callback. 

主站蜘蛛池模板: 黄梅县| 西青区| 民乐县| 石门县| 邵武市| 隆回县| 屏东市| 会宁县| 乌鲁木齐市| 织金县| 蓬莱市| 南开区| 锦屏县| 邛崃市| 台前县| 霍林郭勒市| 英吉沙县| 弥渡县| 睢宁县| 建水县| 甘南县| 苍溪县| 乐亭县| 潢川县| 赣榆县| 夹江县| 任丘市| 宣城市| 巩留县| 闻喜县| 九台市| 靖安县| 西林县| 榆林市| 河北区| 阳原县| 安泽县| 大庆市| 汉源县| 樟树市| 北票市|