Loading... `http://zh.highscore.de/cpp/boost/` # 函数指针 Boost中封装了函数指针的,没用boost是这么写的 `typedef void (*p)(int ,char*); 定义一个没有返回值的 函数指针 参数分别是int char*类型` `Boost只需要boost::function<int(const char*)>f=APIAddress即可` ![image.png](https://www.irohane.top/usr/uploads/2021/11/4272611087.png) ```cpp #include <boost/function.hpp> #include <iostream> #include <cstdlib> #include <cstring> int main() { //原来 typedef void (*p)(int ,char*); 定义一个没有返回值的 函数指针 参数分别是int char boost::function<int(const char*)> f = std::atoi; std::cout << f("1609") << std::endl; f = std::strlen; std::cout << f("1609") << std::endl; } ``` ## 异常 为赋值就被调用->boost::bad_function_call 异常 ```cpp #include <boost/function.hpp> #include <iostream> int main() { try { boost::function<int (const char*)> f; f(""); } catch (boost::bad_function_call &ex) { std::cout << ex.what() << std::endl; } } ``` # Bosst.Bind-\<vector\> 官方文档理解比较难。这里只举例常用到的一些,后续如果有用到会进行补充。 <span style='color:Red'>注意带引用的参数,必须要配合Boost.Ref</span> 因为 `add()` 函数要求两个参数,两个参数都必须传递给 `boost::bind()`。 第一个参数是常数值10,而第二个参数则是一个怪异的 _1。 _1 被称为占位符(placeholder),定义于 Boost.Bind。 除了 _1,Boost.Bind 还定义了 _2 和 _3。 通过使用这些占位符,`boost::bind()` 可以变为一元、二元或三元的函数。 对于 _1, `boost::bind()` 变成了一个一元函数 - 即只要求一个参数的函数。 这是必需的,因为 `std::for_each()` 正是要求一个一元函数作为其第三个参数。 当这个程序执行时,`std::for_each()` 对容器 v 中的第一个元素调用该一元函数。 元素的值通过占位符 _1 传入到一元函数中。 这个占位符和常数值被进一步传递到 `add()` 函数。 通过使用这种机制,`std::for_each()` 只看到了由 `boost::bind()` 所定义的一元函数。 而 `boost::bind()` 本身则只是调用了另一个函数,并将常数值或占位符作为参数传入给它。 ```cpp #include <boost/bind.hpp> #include <iostream> #include <vector> #include <algorithm> void add(int i, int j) { std::cout << i + j << std::endl; } int main() { std::vector<int> v; v.push_back(1); v.push_back(3); v.push_back(2); std::for_each(v.begin(), v.end(), boost::bind(add, 10, _1)); std::sort(v.begin(), v.end(), compare); std::sort(v.begin(), v.end(), boost::bind(compare, _2, _1)); } ``` `boost::bind()` 的函数带有至少一个引用参数时,Boost.Ref 就很重要了。 由于 `boost::bind()` 会复制它的参数,所以引用必须特别处理。 ```cpp #include <boost/bind.hpp> #include <iostream> #include <vector> #include <algorithm> void add(int i, int j, std::ostream &os) { os << i + j << std::endl; } int main() { std::vector<int> v; v.push_back(1); v.push_back(3); v.push_back(2); std::for_each(v.begin(), v.end(), boost::bind(add, 10, _1, boost::ref(std::cout))); } ``` # 信号 Boost.Signals 所实现的模式被命名为 '信号至插槽' (signal to slot),它基于以下概念:当对应的信号被发出时,相关联的插槽即被执行。 原则上,你可以把单词 '信号' 和 '插槽' 分别替换为 '事件' 和 '事件处理器'。 不过,由于信号可以在任意给定的时间发出,所以这一概念放弃了 '事件' 的名字。 因此,Boost.Signals 没有提供任何类似于 '事件' 的类。 相反,它提供了一个名为 `boost::signal` 的类,定义于 `boost/signal.hpp`. 实际上,这个头文件是唯一一个需要知道的,因为它会自动包含其它相关的头文件。 ``` //http://zh.highscore.de/cpp/boost/ #include <iostream> #include <boost/signals2.hpp> #include <boost/function.hpp> void func1() { std::cout << "Hello" << std::endl; } void func2() { std::cout << ", world!" << std::endl; } int main() { boost::function<void()> f; //也可以绑定指针 //void() 返回值 boost::signals2::signal<void()> s; //使用默认信号 如果两个函数返回的话只会接受最后一个函数的参数 如果都要返回需要重载类 s.connect(func1); s.connect(func2); s.disconnect(func2); //释放函数与信号的关联 s.num_slots(); //返回已关联函数的数量 Empty()检测空 s.disconnect_all_slots(); //释放所有关联 s(); //函数可以通过由 boost::connection 所提供的 connect() 和 disconnect() 方法的帮助来进行管理。 由于 connect() 会返回一个类型为 boost::signals::connection 的值,它们可以通过其它方法来管理。 //signals2::connection对象不再拥有block()方法等等。 boost::signals2::connection c = s.connect(func2); } ``` # 字符串 ```cpp #include <boost/algorithm/string.hpp> #include <boost/algorithm/string/regex.hpp> #include <boost/tokenizer.hpp> #include <vector> #include <locale> #include <iostream> int main() { std::locale::global(std::locale("German")); //设置德语的语言编码方式 std::string s = "Boris Schäling"; boost::iterator_range<std::string::iterator> r = boost::algorithm::find_first(s, "Boris"); std::cout << r << std::endl; //输出找到的 r = boost::algorithm::find_first(s, "Sch"); std::cout << r << std::endl; //大小写控制 std::cout << boost::algorithm::to_upper_copy(s) << std::endl; std::cout << boost::algorithm::to_upper_copy(s, std::locale("German")) << std::endl; //字符串拼接 std::vector<std::string> v; v.push_back("Boris"); v.push_back("Schäling"); std::cout << boost::algorithm::join(v, " ") << std::endl; //去除空格 std::string _s = "\t --Boris Schäling-- \t"; std::cout << "." << boost::algorithm::trim_left_copy(_s) << "." << std::endl; //去除左侧空格 std::cout << "." << boost::algorithm::trim_right_copy(_s) << "." << std::endl; //右侧空格 std::cout << "." << boost::algorithm::trim_copy(_s) << "." << std::endl; //两侧空格 //检测是不是数字 std::string s_Numbers = "123456789Boris Schäling123456789"; std::cout << "." << boost::algorithm::trim_left_copy_if(s_Numbers, boost::algorithm::is_digit()) << "." << std::endl; //如果左侧是数字就删除左侧 std::cout << "." << boost::algorithm::trim_right_copy_if(s_Numbers, boost::algorithm::is_digit()) << "." << std::endl; //如果右侧是数字删除右侧 std::cout << "." << boost::algorithm::trim_copy_if(s_Numbers, boost::algorithm::is_digit()) << "." << std::endl; //删除两边数字 //检测字符串开始和结束 std::cout << boost::algorithm::starts_with(s, "Boris") << std::endl; //开始 std::cout << boost::algorithm::ends_with(s, "Schäling") << std::endl; //结束 std::cout << boost::algorithm::contains(s, "is") << std::endl; //是否有 //替换 std::locale::global(std::locale("German")); std::cout << boost::algorithm::replace_first_copy(s, "B", "D") << std::endl; //第一个B替换 std::cout << boost::algorithm::replace_nth_copy(s, "B", 1, "D") << std::endl; //匹配全部第二个参数 将第三个参数作为下表 选择第几个下标作为替换 std::cout << boost::algorithm::replace_last_copy(s, "B", "D") << std::endl; //最后的B替换D std::cout << boost::algorithm::replace_all_copy(s, "B", "D") << std::endl; //全部替换 std::cout << boost::algorithm::replace_head_copy(s, 9, "Doris") << std::endl; //将前九个字符更换为参数三 std::cout << boost::algorithm::replace_tail_copy(s, 8, "Becker") << std::endl; //第8个之后更换 为参数三 //正则表达式 // boost::regex 用于正则表达式 boost::smatch用于保存搜索结果 boost::iterator_range<std::string::iterator> re_r = boost::algorithm::find_regex(s, boost::regex("\\w\\s\\w")); std::cout << re_r << std::endl; boost::regex expr("\\w+\\s\\w+"); std::cout << boost::regex_match(s, expr) << std::endl; //用于字符串与正则表达式的比较。 在整个字符串匹配正则表达式时其返回值为 true //---------------------------------------------------------------------- //boost::regex_search() 可用于在字符串中搜索正则表达式 boost::regex _1expr("(\\w+)\\s(\\w+)"); boost::smatch what; if (boost::regex_search(s, what, _1expr)) { std::cout << what[0] << std::endl; //what[0] 指向整个字符串 std::cout << what[1] << " " << what[2] << std::endl; //获取的结果 } //---------------------------------------------------------------------- boost::regex _2expr("\\s"); std::string fmt("_"); std::cout << boost::regex_replace(s, _2expr, fmt) << std::endl; //regex_replace 匹配之后替换 //---------------------------------------------------------------------- boost::regex _3expr("(\\w+)\\s(\\w+)"); std::string fmt1("\\2 \\1"); std::cout << boost::regex_replace(s, _3expr, fmt1) << std::endl;//显示为Schäling Boris 由于德语编码问题,正则没用匹配上?ling std::cout << boost::regex_replace(s, _3expr, fmt1, boost::regex_constants::format_literal) << std::endl; //看不到效果 //---------------------------------------------------------------------- } ``` ## 字符串词汇分割 ```cpp #include <boost/algorithm/string.hpp> #include <boost/algorithm/string/regex.hpp> #include <boost/tokenizer.hpp> #include <vector> #include <locale> #include <iostream> int main() { //Boost.Tokenizer 词汇分割器 typedef boost::tokenizer<boost::char_separator<char> > tokenizer; // boost::char_separator 类默认将空格和标点符号视为分隔符 函数调用了 std::isspace() 函数和 std::ispunct 函数 std::string tks = "Boost C++ libraries"; tokenizer tok(tks); //将tks 中以 空格分开 for (tokenizer::iterator it = tok.begin(); it != tok.end(); ++it) std::cout << *it << std::endl; std::cout << "" << std::endl; //符号作为分隔符 typedef boost::tokenizer<boost::char_separator<char> > tokenizer1; //默认情况下会删除分隔符 如果sep加上第三个分割符号就会显示 boost::char_separator<char> sep(" "); tokenizer1 tok1(tks, sep); for (tokenizer1::iterator it = tok1.begin(); it != tok1.end(); ++it) std::cout << *it << std::endl; std::cout << "" << std::endl; typedef boost::tokenizer<boost::char_separator<char> > tokenizer2; boost::char_separator<char> sep2(" ", "+"); //空格仍然被视为分隔符 第二个参数指定了需要显示的分隔符。 在不提供此参数的情况下,将不显示任何分隔符 tokenizer2 tok2(tks, sep2); for (tokenizer2::iterator it = tok2.begin(); it != tok2.end(); ++it) std::cout << *it << std::endl; std::cout << "" << std::endl; //Wchar 类型遍历 std::wstring ws = L"Boost C++ libraries"; typedef boost::tokenizer<boost::char_separator<wchar_t>, std::wstring::const_iterator, std::wstring> tokenizer3; boost::char_separator<wchar_t> sep3(L" "); tokenizer3 tok3(ws, sep3); for (tokenizer3::iterator it = tok3.begin(); it != tok3.end(); ++it) std::wcout << *it << std::endl; std::cout << "" << std::endl; typedef boost::tokenizer<boost::escaped_list_separator<char> > wtokenizer1; std::string ws1 = "Boost,\"C++ libraries\""; wtokenizer1 wtok1(ws1); for (wtokenizer1::iterator it = wtok1.begin(); it != wtok1.end(); ++it) std::cout << *it << std::endl; std::cout << "" << std::endl; //根据距离进行切割 不区分是否大小写了 std::string css = "Boost C++ libraries"; typedef boost::tokenizer<boost::offset_separator> wtokenizer3; int offsets[] = { 5, 5, 9 }; boost::offset_separator wsep1(offsets, offsets + 3); wtokenizer3 wtok2(css, wsep1); for (wtokenizer3::iterator it = wtok2.begin(); it != wtok2.end(); ++it) std::cout << *it << std::endl; } ``` # 线程 ``` #include <boost/thread.hpp> ```` # ASIO ```cpp // asio程序必须的io_service对象 boost::asio::io_service ios; // 具体的服务器地址与端口 boost::asio::ip::tcp::endpoint endpotion(boost::asio::ip::tcp::v4(), 13695); // 创建acceptor对象,当前的IPV4作为服务器地址(127.0.0.1 || 0.0.0.0),接受端口13695的消息. boost::asio::ip::tcp::acceptor acceptor(ios, endpotion); // 打印当前服务器地址 std::cout << "addr: " << acceptor.local_endpoint().address() << std::endl; // 打印当前服务器端口 std::cout << "port: " << acceptor.local_endpoint().port() << std::endl; //创建一个临时socket对象 用来对接新的socket boost::asio::ip::tcpsocket socket(ios); //阻塞等待客户端链接,连接成功返回socket,accept函数调取socket acceptor.accept(socket); //打印与本机服务器取得连接的客户端IP地址 socket.remote_endpoint().address(); std::string msg; //阻塞发送者名称到客户端 socket.write_some(boost::asio::buffer("hello csnd")); //阻塞接受客户端发送来的数据 socket.read_some(boost::asio::buffer(msg)); //打印 std::cout<<"client reply: "<<msg.c_str()<<std::endl; try {} catch (std::exception& _e) { std::cout << "server exceptional." << std::endl; std::cout << _e.what() << std::endl; } ``` # 编译 官网**下载** 最新的boost,www.boost.org 。 **安装** ,解压后运行bootstrap.bat文件。稍等一小会就OK。 ![image.png](https://www.irohane.top/usr/uploads/2021/12/345296102.png) **编译boost库** 。注意一定要使用VS2019的x86本机工具命令提示,这个可以在VS2019的安装菜单里面找到。进入命令行提示,输入下面的内容: 32位生成 ``` bjam -j4 --debug-symbols=on --build-type=complete toolset=msvc-14.2 threading=multi runtime-link=shared address-model=32 --stagedir="D:\FV\Boost" ``` 64位生成 `b2.exe stage --toolset=msvc-14.2 --stagedir="D:\FV\Boost" link=static runtime-link=shared runtime-link=static threading=multi address-model = 64 debug release` 注意这里指定的运行库类型是动态链接库: runtime-link=shared 当然也可以选择静态库,这样指定即可: runtime-link=static 编译后默认在当前路径下的stage下 可以使用--stagedir="D:\FV\Boost" 来改变。 最后修改:2022 年 10 月 20 日 © 允许规范转载 赞 0 如果觉得我的文章对你有用,请随意赞赏