Boost(三)——函数对象

接下来的几章内容我就结合Boost官网,补充下官网的难以理解的点,并且写出练习的答案,如果有不同意见的可以留言,谢谢。

原题:

1、简化以下程序,将函数对象 divide_by 转换为一个函数,并将 for 循环替换为用一个标准的 C++ 算法来输出数据:

#include <algorithm> 
#include <functional> 
#include <vector> 
#include <iostream> 

class divide_by 
  : public std::binary_function<int, int, int> 
{ 
public: 
  int operator()(int n, int div) const 
  { 
    return n / div; 
  } 
}; 

int main() 
{ 
  std::vector<int> numbers; 
  numbers.push_back(10); 
  numbers.push_back(20); 
  numbers.push_back(30); 

  std::transform(numbers.begin(), numbers.end(), numbers.begin(), std::bind2nd(divide_by(), 2)); 

  for (std::vector<int>::iterator it = numbers.begin(); it != numbers.end(); ++it) 
    std::cout << *it << std::endl; 
} 

 transform函数有两种

第一种:一元函数,从唯一容器头遍历到尾,运行Func函数,将返回值写入容器中

transform(_InIt _First, _InIt _Last,
		_OutIt _Dest, _Fn1 _Func)

第二种:二元函数,从第一个容器头遍历到尾,同时遍历第二个容器,运行Func函数,将返回值写入(第一个或第二个)容器中。

要注意的是,容器一和容器二的大小要一致。

transform(_InIt1 _First1, _InIt1 _Last1,
		_InTy (&_First2)[_InSize], _OutIt _Dest, _Fn2 _Func)

 解答:

#include <algorithm> 
#include <functional> 
#include <vector> 
#include <iostream> 
#include <boost\bind.hpp>
#include <boost\lambda\lambda.hpp>
#include <boost/function.hpp> 
int main()
{
	std::vector<int> numbers;
	numbers.push_back(10);
	numbers.push_back(20);
	numbers.push_back(30);

	boost::function<int(int, int) > f = divide_by();
	transform(numbers.begin(), numbers.end(), numbers.begin(), boost::bind(f,_1, 2));
	for_each(numbers.begin(), numbers.end(), cout << boost::lambda::_1 <<"\n");
}

boost::function<int(int, int)> f :

第一个int 是函数返回值类型。

括号中的两个int 是 代表函数参数 是 两个int类型的参数。

_1:是占位符,这里代表numbers容器遍历的值。

devide_by函数需要两个参数,依据题意,第二个参数是2。

tramsform函数将结果写入numbers容器(覆盖了原值)

利用for_each(c++标准库算法)遍历,以及boost::lambda输出容器存储的每个值。

2、简化以下程序,将两个 for 循环都替换为标准的 C++ 算法:

#include <string> 
#include <vector> 
#include <iostream> 

int main() 
{ 
  std::vector<std::string> strings; 
  strings.push_back("Boost"); 
  strings.push_back("C++"); 
  strings.push_back("Libraries"); 

  std::vector<int> sizes; 

  for (std::vector<std::string>::iterator it = strings.begin(); it != strings.end(); ++it) 
    sizes.push_back(it->size()); 

  for (std::vector<int>::iterator it = sizes.begin(); it != sizes.end(); ++it) 
    std::cout << *it << std::endl; 
} 

解答:

#include <string> 
#include <vector> 
#include <iostream> 
#include <algorithm>
#include <boost\lambda\lambda.hpp>
#include <boost\bind.hpp>
using namespace std;
int main()
{
	std::vector<std::string> strings;
	strings.push_back("Boost");
	strings.push_back("C++");
	strings.push_back("Libraries");

	std::vector<int> sizes;

	for (std::vector<std::string>::iterator it = strings.begin(); it != strings.end(); ++it)
		sizes.push_back(it->size());

	for (std::vector<int>::iterator it = sizes.begin(); it != sizes.end(); ++it)
		std::cout << *it << std::endl;

	transform(strings.begin(), strings.end(), sizes.begin(), boost::bind(&string::size,_1));
	for_each(sizes.begin(), sizes.end(), cout << boost::lambda::_1 << "\n");
}

利用transform 占位符(_1)接受strings容器的值,boost::bind 绑定字符串的size函数

 boost::lambda 输出 不能用 endl 只能用"\n"

3、简化以下程序,修改变量 processors 的类型,并将 for 循环替换为标准的 C++ 算法:

#include <vector> 
#include <iostream> 
#include <cstdlib> 
#include <cstring> 

int main() 
{ 
  std::vector<int(*)(const char*)> processors; 
  processors.push_back(std::atoi); 
  processors.push_back(reinterpret_cast<int(*)(const char*)>(std::strlen)); 

  const char data[] = "1.23"; 

  for (std::vector<int(*)(const char*)>::iterator it = processors.begin(); it != processors.end(); ++it) 
    std::cout << (*it)(data) << std::endl; 
} 

解答:

#include <vector> 
#include <iostream> 
#include <cstdlib> 
#include <cstring> 
#include <boost\bind.hpp>
#include <algorithm>

#include <iterator>
using namespace std;

void printRusult( int (*fun)(const char*) , const char * data)
{
	cout << fun(data) << endl;
}
int main()
{
	std::vector<int(*)(const char*)> processors;
	processors.push_back(std::atoi);
	processors.push_back(reinterpret_cast<int(*)(const char*)>(std::strlen));

	const char data[] = "1.23";

	for (std::vector<int(*)(const char*)>::iterator it = processors.begin(); it != processors.end(); ++it)
		std::cout << (*it)(data) << std::endl;

	for_each(processors.begin(), processors.end(), boost::bind(printRusult, _1, data));
	system("pause");
}

占位符是针对参数,而非函数,需要写一个函数将vector容器中的函数指针获取并运行,利用boost::bind绑定该参数。

解答二

#include <vector> 
#include <iostream> 
#include <cstdlib> 
#include <cstring> 
#include <boost\bind.hpp>
#include <algorithm>
#include <boost\function.hpp>
#include <iterator>
using namespace std;

void printRusult( int (*fun)(const char*) , const char * data)
{
	cout << fun(data) << endl;
}
int main()
{
	std::vector<int(*)(const char*)> processors;
	processors.push_back(std::atoi);
	processors.push_back(reinterpret_cast<int(*)(const char*)>(std::strlen));

	static const char data[] = "1.23";

	for (std::vector<int(*)(const char*)>::iterator it = processors.begin(); it != processors.end(); ++it)
		std::cout << (*it)(data) << std::endl;

	for_each(processors.begin(), processors.end(), [&](int(*f)(const char*)) {boost::function<int(const char*)> ff = f;
	ff(data);});
	system("pause");
}

 结合c++11特性的Lambda表达式,以及将 data 类型变成静态变量。

猜你喜欢

转载自blog.csdn.net/u012198575/article/details/83541555