一、基本语言特性
c++20高级编程(第5版)pdf详细介绍了c++20的一些新特性,包括模块化、协程、概念、反射、consteval函数、三路比较运算符和lambda表达式的扩展等。其中,模块化是c++20最重要的新特性之一,它的出现使得c++的头文件依赖问题得到了极大的改善。
下面是一个使用c++20模块化的示例代码:
// file: greet/greeting.hpp export module greet.greeting; #include <string> export std::string get_greeting(const std::string& name);
// file: greet/greeting.cpp import greet.greeting; std::string get_greeting(const std::string& name) { return "Hello, " + name + "!"; }
在上面的示例中,我们定义了一个模块greet.greeting,其中包含了get_greeting函数的声明。在实现文件中,我们使用import指令引入模块并实现get_greeting函数。
另一个新特性是协程,它允许开发者将函数暂停和恢复。下面是一个使用协程的示例代码:
#include <coroutine> #include <iostream> struct Task { struct promise_type { auto initial_suspend() { return std::suspend_never{}; } auto final_suspend() { return std::suspend_never{}; } auto return_void() {} }; }; Task foo() { std::cout << "Hello, "; co_await std::suspend_always{}; std::cout << "World!\n"; } int main() { foo(); }
在上面的示例中,我们定义了一个可暂停的函数foo,并在其中使用co_await关键字暂停函数。当函数在后续调用时恢复时,会从之前暂停的位置继续执行。
二、STL和算法库
c++20引入了一些新的STL容器和算法,同时也对一些常用的容器和算法进行了扩展。下面是一些示例代码:
#include <ranges> #include <vector> #include <algorithm> #include <execution> int main() { std::vector<int> v = {1, 2, 3, 4, 5}; auto is_even = [](int x) { return x%2 == 0; }; std::ranges::partition(v, is_even); std::ranges::sort(v); std::ranges::reverse(v); std::ranges::for_each(std::execution::par, v, [](int x) { std::cout << x << " "; }); }
在上面的示例中,我们使用了ranges库中的函数和算法对vector进行了分区、排序、反转和并行for_each操作。
三、元编程和反射
c++20对元编程和反射也进行了一些扩展,包括constexpr if、requires表达式、编译期lambda表达式、反射接口和type_identity等特性。
下面是一个使用constexpr if的示例代码:
template <typename T> void print(T x) { if constexpr (std::is_integral_v<T>) { std::cout << "integer: " << x << std::endl; } else if constexpr (std::is_floating_point_v<T>) { std::cout << "floating point: " << x << std::endl; } else if constexpr (std::is_pointer_v<T>) { std::cout << "pointer: " << x << std::endl; } } int main() { int a = 1; double b = 1.2; int* c = &a; print(a); print(b); print(c); return 0; }
在上面的示例中,我们定义了一个print函数,它可以通过constexpr if在编译期间根据参数类型进行不同的处理。
下面是一个使用反射功能的示例代码:
#include <iostream> #include <string> #include <typeinfo> #include <typeindex> #include <unordered_map> struct A { int n; double d; std::string s; }; struct Reflector { static std::unordered_map<std::type_index, std::string> names; template <typename T> static void register_name(const std::string& name) { names[std::type_index(typeid(T))] = name; } }; std::unordered_map<std::type_index, std::string> Reflector::names; #define REGISTER_NAME(T) Reflector::register_name<T>(#T) int main() { REGISTER_NAME(A); std::cout << Reflector::names[std::type_index(typeid(A))] << std::endl; return 0; }
在上面的示例中,我们定义了一个Reflector类来注册和管理类型的名称,通过反射获取了A的类型名称。
四、多线程编程
c++20在多线程编程方面也有了一些改进,包括std::jthread、std::stop_token、std::latch、std::barrier和std::semaphore等新特性。
下面是一个使用std::jthread和std::stop_token的示例代码:
#include <jthread> #include <chrono> #include <iostream> void task(std::stop_token token) { while (!token.stop_requested()) { std::cout << "task running...\n"; std::this_thread::sleep_for(std::chrono::seconds(1)); } std::cout << "task stopped!\n"; } int main() { std::jthread th(task); std::this_thread::sleep_for(std::chrono::seconds(5)); th.request_stop(); th.join(); return 0; }
在上面的示例中,我们使用std::jthread创建了一个线程,并使用std::stop_token来控制线程的停止。
五、网络编程
c++20在网络编程方面也有了一些改进,包括网络库、协程和异步等多种方式支持网络编程。其中,网络库比较方便易用,下面是一个使用网络库的示例代码:
#include <iostream> #include <boost/asio.hpp> void echo(boost::asio::ip::tcp::socket socket) { try { boost::asio::streambuf buf; boost::asio::read_until(socket, buf, '\n'); std::string data = boost::asio::buffer_cast<const char*>(buf.data()); boost::asio::write(socket, boost::asio::buffer(data)); } catch(std::exception& e) { std::cerr << "exception: " << e.what() << std::endl; } } int main() { try { boost::asio::io_context io_context; boost::asio::ip::tcp::acceptor acceptor(io_context, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 8888)); while (true) { boost::asio::ip::tcp::socket socket(io_context); acceptor.accept(socket); std::thread(echo, std::move(socket)).detach(); } } catch(std::exception& e) { std::cerr << "exception: " << e.what() << std::endl; } return 0; }
在上面的示例中,我们使用boost::asio网络库来实现了一个最简单的echo服务器。