接下来的几章内容我就结合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 类型变成静态变量。