C++ Research and Development of Generic Programming Lecture Fourteen [Commonly Used Traversal Algorithms]

一、for_each

Function description:

  • Implement traversal container

Function prototype:

  • for_each(iterator beg, iterator end, _func);

    // The traversal algorithm traverses the container elements

    // beg starts iterator

    // end ends the iterator

    // _func function or function object

Dissecting the source code of for_each:

// FUNCTION TEMPLATE for_each
template <class _InIt, class _Fn>
_CONSTEXPR20 _Fn for_each(_InIt _First, _InIt _Last, _Fn _Func) { // perform function for each element [_First, _Last)
    _Adl_verify_range(_First, _Last);
    auto _UFirst      = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    for (; _UFirst != _ULast; ++_UFirst) {
        _Func(*_UFirst);
    }

    return _Func;
}

Here the first parameter is the head iterator of the container, the second parameter is the tail iterator, and the third is to pass a function. 

Note that the function name is passed here.

What is the function name? The function name is actually the address of the function.

In other words, we can write:

vector<int> v;
	v.push_back(1);
	v.push_back(0);
	v.push_back(1);
	v.push_back(0);
	v.push_back(1);
	void(*p)(int) = print01;
	(*p)(5);
	for_each(v.begin(), v.end(), p);

Use a function pointer p to store the address of the print01 function,

Then put the pointer in for_each, and it will work as well.

Continue to look at the source code:

 Then an iterator move is made, and each move will dereference the function pointer and make a function call.

The parameter of the call is: the element pointed to by the iterator.

Example:

#include <algorithm>
#include <vector>

//普通函数
void print01(int val) 
{
	cout << val << " ";
}
//函数对象
class print02 
{
 public:
	void operator()(int val) 
	{
		cout << val << " ";
	}
};

//for_each算法基本用法
void test01() {

	vector<int> v;
	for (int i = 0; i < 10; i++) 
	{
		v.push_back(i);
	}

	//遍历算法
	for_each(v.begin(), v.end(), print01);
	cout << endl;

	for_each(v.begin(), v.end(), print02());
	cout << endl;
}

int main() {

	test01();

	system("pause");

	return 0;
}

 

Two, transform

Function description:

  • Move the container to another container

Function prototype:

  • transform(iterator beg1, iterator end1, iterator beg2, _func);

//beg1 source container start iterator

//end1 source container end iterator

//beg2 target container start iterator

//_func function or function object

Source code:

// FUNCTION TEMPLATE transform
template <class _InIt, class _OutIt, class _Fn>
_CONSTEXPR20 _OutIt transform(const _InIt _First, const _InIt _Last, _OutIt _Dest, _Fn _Func) {
    // transform [_First, _Last) with _Func
    _Adl_verify_range(_First, _Last);
    auto _UFirst      = _Get_unwrapped(_First);
    const auto _ULast = _Get_unwrapped(_Last);
    auto _UDest       = _Get_unwrapped_n(_Dest, _Idl_distance<_InIt>(_UFirst, _ULast));
    for (; _UFirst != _ULast; ++_UFirst, (void) ++_UDest) {
        *_UDest = _Func(*_UFirst);
    }

    _Seek_wrapped(_Dest, _UDest);
    return _Dest;
}

Here first specify the start iterator and the end iterator of the original function, and then the for loop:

Each time, perform a function operation on the value pointed to by the iterator, and then put it into the target iterator.

After running, both iterators perform ++ operations. 

Example:

#include<vector>
#include<algorithm>

//常用遍历算法  搬运 transform

class TransForm
{
public:
	int operator()(int val)
	{
		return val;
	}

};

class MyPrint
{
public:
	void operator()(int val)
	{
		cout << val << " ";
	}
};

void test01()
{
	vector<int>v;
	for (int i = 0; i < 10; i++)
	{
		v.push_back(i);
	}

	vector<int>vTarget; //目标容器

	vTarget.resize(v.size()); // 目标容器需要提前开辟空间

	transform(v.begin(), v.end(), vTarget.begin(), TransForm());

	for_each(vTarget.begin(), vTarget.end(), MyPrint());
}

int main() {

	test01();

	system("pause");

	return 0;
}

Note: The target container for transportation must open up space in advance, otherwise it cannot be moved normally.

 

Guess you like

Origin blog.csdn.net/Kukeoo/article/details/114108474