// 模板参数类型区分 template <class T> static std::string cppdemangle() { std::string s{cppdemangle(typeid(std::remove_cv_t<std::remove_reference_t<T>>))}; if (std::is_const_v<std::remove_reference_t<T>>) s += " const"; if (std::is_volatile_v<std::remove_reference_t<T>>) s += " volatile"; if (std::is_lvalue_reference_v<T>) s += " &"; if (std::is_rvalue_reference_v<T>) s += " &&"; return s; } // 显示转换枚举值 template <class T, std::enable_if_t<std::is_enum_v<T>, int> = 0> constexpr std::underlying_type_t<T> to_underlying(T t) noexcept { return static_cast<std::underlying_type_t<T>>(t); } template <class T, std::enable_if_t<!std::is_enum_v<T>, int> = 0> constexpr T to_underlying(T t) noexcept { return t; } //文件操作 static std::string file_get_content(std::string const &path) { std::ifstream fin(path); std::string content; std::istreambuf_iterator<char> iit(fin), eiit; std::back_insert_iterator<std::string> sit(content); std::copy(iit, eiit, sit); return content; } static void file_put_content(std::string const &path, std::string const &content) { std::ofstream fout(path); fout << content; } static bool file_exists(std::string const &path) { std::ifstream fin(path); return (bool)fin; } // win min max冲突 #ifdef _WIN32 #ifndef NOMINMAX #define NOMINMAX #endif #ifndef _USE_MATH_DEFINES #define _USE_MATH_DEFINES #endif /* FUN FACT: DID YOU KNOW THAT MICROSOFT BUYS GITHUB? */ #if __has_include(<windows.h>) #include <windows.h> #elif __has_include(<math.h>) #include <math.h> #endif /* FUN FACT: DID YOU KNOW THAT MICROSOFT INVENTS VSCODE? */ #ifdef min #undef min #endif #ifdef max #undef max #endif #ifdef near #undef near #endif #ifdef far #undef far #endif #endif // 耗时 #define TICK(x) auto bench_##x = std::chrono::steady_clock::now(); #define TOCK(x) std::printf("%s: %lfs\n", #x, std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::steady_clock::now() - bench_##x).count()); // 随机字符串生成 inline std::string randomStringGenerator(const int len) { std::string res; static const char alphanum[] = "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "abcdefghijklmnopqrstuvwxyz"; for (int i = 0; i < len; ++i) res += alphanum[((size_t)std::rand() % (sizeof(alphanum) - 1))]; return res; } // C++20之三目运算 template<typename T> void compare(T x, T y) { auto ret = x <=> y; std::cout << "name: " << typeid(ret).name() << std::endl; if (ret < 0) std::cout << "x < y:" << x << "," << y << std::endl; else if (ret == 0) std::cout << "x == y:" << x << "," << y << std::endl; else std::cout << "x > y:" << x << "," << y << std::endl; } // C++20之字符与数值转换 #include <charconv> // std::to_chars: converts an integer or floating-point value to a character sequence std::array<char, 10> buffer; // 注意:std::errc没有到bool的隐式转换,所以你不能像下面这样检查: if (res.ec) {} or if (!res.ec) {} if (auto [ptr, ec] = std::to_chars(buffer.data(), buffer.data() + buffer.size(), val_int); ec == std::errc()) { std::cout << "str:" << std::string_view(buffer.data(), ptr - buffer.data()) << "\n"; // str:88 *ptr = '\0'; // 保证结尾有一个空字符 std::cout << "buffer:" << buffer.data() << "\n"; // buffer:88 } else { std::cerr << "fail to call to_char:" << std::make_error_code(ec).message() << "\n"; return -1; } auto str2 = "456.789"; float val2{ 0.f }; auto [ptr2, ec2] = std::from_chars(str2.data(), str2.data() + str2.size(), val2); if (ec2 == std::errc()) std::cout << "val2:" << val2 << "\n"; // val2:456.789 else if (ec2 == std::errc::invalid_argument) std::cerr << "Error: this is not a number: " << str2 << "\n"; else if (ec2 == std::errc::result_out_of_range) std::cerr << "Error: this number is larger than an float: " << str2 << "\n"; else std::cerr << "fail to call from_chars:" << std::make_error_code(ec2).message() << "\n"; // C++17之并行策略 #include <algorithm> #include <iostream> #include <vector> #include <execution> std::vector<int> v = { 5, 2, 3, 1, 4 }; std::vector<int> v2(5); std::sort(std::execution::seq, v.begin(), v.end()); // 向量 std::for_each(std::execution::unseq, v.begin(), v.end(), [](int x) { std::cout << x << " "; }); // 向量化单线程 std::transform(std::execution::par, v1.begin(), v1.end(), v2.begin(), [](int x) { return x * x; }); // 多线程 std::for_each(std::execution::par_unseq, v.begin(), v.end(), [](int x) { std::cout << x << " "; }); // 硬软件或SMID https://www.geeksforgeeks.org/execution-policy-of-stl-algorithms-in-modern-cpp/ // C++头文件定义全局变量 class InlineVariable { public: inline static int var{ 10 }; // 不带inline,则只能在类外初始化;即使在类外初始化,如果被多个cpp文件包含也会error;带inline后,即使被多个cpp文件包含也OK inline static std::string name{ "Messy_Test" }; // 整个程序中只有一个 inline static thread_local int count{ 1 }; // 每个线程有一个 std::string city{ "BeiJing" }; // 每个实例有一个 }; inline InlineVariable inline_variable; // 不带inline,则会报重复定义;带inline后,即使被多个cpp文件包含也OK // 获取实际对象地址 std::addressof(c)C++11中包含了以下几种String literal,
- "" : Ordinary string literal
- L"" : Wide string literal
- u8"" : UTF-8 string literal
- u"" : UTF-16 string literal
- U"" : UTF-32 string literal
- R"" : Raw string literal
C++ 现代教程二-CSDN博客