这里以下面这部分代码为示例进行分析,在虚幻之后的版本中可能改变但大同小异。 FORCEINLINE void AddSharedReference() { SharedReferenceCount.FetchAdd(1, EMemoryOrder::Relaxed); } void ReleaseSharedReference() { RefCounter::ValueType OldSharedReferenceCount = SharedReferenceCount.FetchSub(1,
分类: C++
在 C++ STL 中包含多种不同的字符转换方式,主要分为继承自 C 风格函数式转换和 C++ 刻面对象。 本地环境和刻面 本地环境是一系列刻面的集合,描述了本地字符的编码,刻面描述了各种文本处理的方案。 例如在默认的 "C" 本地环境中,本地窄多字节编码指的是 ASCII 码,而在 "Chinese (Simplified)_China.936" 本地环境中,本地窄多字节编码指的是 GBK 码。在 "en_US.UTF-8" 本地环境
struct fenwick_tree_2d_t { lli n, m; array2d_t<lli> tre; fenwick_tree_2d_t(lli n, lli m) : n(n), m(m), tre(n + 1, m + 1, 0) { } lli lowbit(lli x) { return x & -x; } void build(lli** arr) { for (lli i = 1; i <= n; ++i) for (lli j = 1; j &
template <typename T> struct array2d_t { lli n, m; vector<T> data; array2d_t(lli n, lli m) : n(n), m(m), data(n* m) { } array2d_t(lli n, lli m, lli v) : n(n), m(m), data(n* m, v) { } decltype(auto) operator[](tuple<lli, lli> ind) {
struct group_t { struct edge_t { lli u; lli v; lli w; lli nxt; }; lli n; vector<lli> head; vector<edge_t> edge; group_t(lli n) : n(n), head(n + 1, -1), edge(1) { } void add_edge(lli u, lli v, lli w) { edge.push_back({ u, v, w, head[u] });
struct mat { lli n, m; vector<lli> vec; mat(lli n, lli m) : n(n), m(m) { vec.resize(n * m); } lli& at(lli i, lli j) { return vec[(i – 1) * m + j – 1]; } lli at(lli i, lli j) const { return vec[(i – 1) * m + j – 1]; } void zero(lli x = 0) {
C/C++ 参考手册 graph LR Fundamental[基础类型<br/>std::is_fundamental] Void[void<br/>std::is_void] NullPointer[std::nullptr_t<br/>std::is_null_pointer] Arithmetic[算术类型<br/>std::is_arithmetic] FloatingPoint[浮点类型<br/>std::is_floati
中所周知,C++ 中的 struct 来源于 C 语言历史遗留,除了默认作用域为 public 外,与 class 并无区别,理论上可以混用。我们这里通过标准库,以及 Unreal 等工程实践,对 struct 和 class 关键字的选择进行一个总结。 如果类型包含非 public 成员变量,应当选择 class 。 如果类型包含 virtual 函数,应当选择 class 。 如果类型可以 聚合初始化 ,应当考虑 struct 。 如果类型的构造析构以及赋值函数为 = default; 实现
本文完全由 ChatGPT 生成。 std::function 和 std::any 采用构造新对象并交换的实现方式,也有一些其他的优点和好处。例如,这种实现方式可以避免赋值运算符(operator=)抛出异常的情况,从而保证了赋值操作的异常安全性。 例如,如果 std::function 和 std::any 采用直接调用赋值操作的方式实现赋值,那么在赋值操作中如果抛出了异常,就可能导致对象的状态发生改变,从而导致程序的不正常终止。而采用构造新对象并交换的实现方式,可以避免赋值操作中抛出异常的
首先,在 cppreference 上对于这部分的描述节选为。 声明于块作用域且带有 static 或 thread_local 说明符的变量拥有静态或线程存储期,但在控制首次经过其声明时才会被初始化。在其后所有的调用中,声明均被跳过。 如果初始化抛出异常,则不认为变量被初始化,且控制下次经过该声明时将再次尝试初始化。 如果初始化递归地进入正在初始化的变量的块,则行为未定义。 函数内部的静态局部变量的初始化是在函数第一次调用时执行,在之后的调用中不会对其初始化。 在多线程环境下,仍能够保证静态局
类生命周期及常用运算符追踪器 struct FTracker { FTracker() { std::cout << "FTracker()" << std::endl; } FTracker(const FTracker&) { std::cout << "FTracker(const FTracker&)" << std::endl; } FTracker(FTracker&&am
函数签名 参考文档:new – delete 即使不包含 标准库 头文件,版本 可替换分配函数 与 可替换解分配函数 也会在每个翻译单元隐式声明。版本 可替换分配函数 与 可替换解分配函数 可以替换:在程序任意位置定义并在任意源文件的用户提供的拥有相同签名的非成员函数都会替换默认版本。它的声明不需要可见。 这意味着我们在替换全局 new/delete 函数时,无需在 .h 中声明,只需要在 .cpp 中定义他们。 对于某个可以替换的函数,如果程序中提供了它的多个替换,或它有带 inl
template <typename T> void LOrR(T&) { std::cout << "L" << std::endl; } template <typename T> void LOrR(T&&) { std::cout << "R" << std::endl; } template <typename T> void FuncA(
在实现 TypeTraits 时发现标准库的 std::is_scoped_enum 在 C++23 才会正式实装,于是通过翻 Unreal Engine 4 的源码发现了一个巧妙的替代方案,类似如下的实现: NAMESPACE_PRIVATE_BEGIN uint8(&Resolve(int64))[2]; uint8 Resolve(…); template <typename T> struct TIsEnumConvertibleToInt : TBoolCons
PS:由于 WP-Editor.md 的 Bug ,脚本中的 $ 符号不显示,需手动添加。 PS:换成 WP Githuber MD 之后就没有这个 Bug 了。 解决方案 cmake_minimum_required (VERSION 3.8) # Main project string(REGEX REPLACE ".*/(.*)" "\\1" CURRENT_FOLDER ${CMAKE_CURRENT_SOURCE_DIR}) project ($
加锁的原则 规则10.1 多线程 进程并行访问共享资源时 一定要加锁保护 共享资源包括全局变量,静态变量,共享内存,文件等。 建议封装像智能指针一样的对象对锁进行管理,比如我们就封装了一个 auto_lock ,在构造时申请锁,析构中释放锁,保证不会忘记解锁。 规则10.2 锁的职责单一 每个锁只锁一个唯一共享资源,这样,才能保证锁应用的单一,也能更好的确保加锁的范围尽 量小。对于共享全局资源,应该根据实际需要,每类或每个资源,有一把锁。这样,这把锁只锁对这个资源访问的代码,通常这样的代码都会是
一键跳转至题目 题目描述 机器上有 $n$ 个需要处理的任务,它们构成了一个序列。这些任务被标号为 $1$ 到 $n$,因此序列的排列为 $1 , 2 , 3 \cdots n$。这 $n$ 个任务被分成若干批,每批包含相邻的若干任务。从时刻 $0$ 开始,这些任务被分批加工,第 ii 个任务单独完成所需的时间是 $T_i$ 。在每批任务开始前,机器需要启动时间 $s$,而完成这批任务所需的时间是各个任务需要时间的总和。 注意,同一批任务将在同一时刻完成。 每个任务的费用是它的完成时刻乘以一个费
洛谷P4781 题解公式 inline int FastPow(int x, int y) { if (y == 1) return x; if (!y) return 1; int tmp = FastPow(x, y >> 1) % mod; return tmp * tmp % mod * (y & 1 ? x : 1) % mod; } inline void Lagrange() { go(i, 1, n, 1) { up = down = 1; go(j, 1,
洛谷P3834 教程视频 #pragma once #include<algorithm> #include<bitset> #include<cmath> #include<cstring> #include<cstdlib> #include<cstdio> #include<complex> #include<fstream> #include<iostream> #include&
lli fac[maxn]; // 阶乘 lli inv[maxn]; // 逆元 lli invf[maxn]; // 逆元的阶乘 inline void init() { fac[0] = 1; for (lli i = 1; i < maxn; ++i) fac[i] = fac[i – 1] * i % mod; inv[1] = 1; for (lli i = 2; i < maxn; ++i) inv[i] = inv[mod % i] * (mod – mod / i)
struct fenwick_tree_t { lli n; vector<lli> tre; fenwick_tree_t(lli n) : n(n), tre(n + 1, 0) { } lli lowbit(lli x) { return x & -x; } void build(lli* arr) { for (lli i = 1; i <= n; ++i) upd(i, arr[i]); } void upd(lli i, lli x) { for (; i
lli gcd(lli x, lli y) { return y ? gcd(y, x % y) : x; }
std::chrono::system_clock::time_point bt = std::chrono::system_clock::now(); std::chrono::system_clock::time_point et = std::chrono::system_clock::now(); std::chrono::nanoseconds dt = std::chrono::duration_cast<std::chrono::nanoseconds>(et – bt
[ 络谷 ] lli dsu[maxn]; lli dis[maxn]; lli num[maxn]; void init_dsu() { for (lli i = 0; i < maxn; ++i) dsu[i] = i; for (lli i = 0; i < maxn; ++i) dis[i] = 0; for (lli i = 0; i < maxn; ++i) num[i] = 1; } lli find_dsu(lli x) { if (dsu[x] == x) r
约定存边方式为从左部到右部的有向边,左右部点编号相同 匈牙利算法 lli mch[maxn]; lli vis[maxn]; bool dfs_hun(lli u, lli dfn) { if (vis[u] == dfn) return false; vis[u] = dfn; for (lli i = head[u]; ~i; i = edge[i].nxt) { lli v = edge[i].v; if (mch[v] == 0 || dfs_hun(mch[v], dfn)) { mc
倍增思想 由 倍增 LCA 改的 lli mw[32][maxn]; lli fa[32][maxn]; lli dep[maxn]; void dfs_mw(lli u) { dep[u] = dep[fa[0][u]] + 1; for (lli i = 1; (1 << i) <= dep[u]; ++i) fa[i][u] = fa[i – 1][fa[i – 1][u]]; for (lli i = 1; (1 << i) <= dep[u]; ++
lli n; lli arr[maxn]; lli lg[maxn]; lli st[maxn][32]; inline lli flg(lli x) { if (lg[x]) return lg[x]; lli tmp = x; lli res = 0; while (tmp) tmp >>= 1, ++res; return lg[x] = res – 1; } inline void init_st() { for (lli i = 1; i <= n; ++i) st[
题目传送门 性质 删除重心后所得的所有子树,节点数不超过原树的1/2,一棵树最多有两个重心;2.树中所有节点到重心的距离之和最小,如果有两个重心,那么他们距离之和相等; 两个树通过一条边合并,新的重心在原树两个重心的路径上; 树删除或添加一个叶子节点,重心最多只移动一条边; 一棵树最多有两个重心,且相邻。 思路 如果找到只有一个重心,那么直接删一个重心的直连边然后加回去就好了。 如果找到两个重心,那么在其中一个重心上找到一个直连点不是另一个重心,删除连另外一个就好了。 如何求树的重心? 先任选一
原理 https://blog.csdn.net/alexfaker/article/details/90199074 模板 https://www.cnblogs.com/iloveori/p/12526461.html#%E8%A7%82%E5%89%8D%E6%8F%90%E7%A4%BA%EF%BC%9A%E8%AF%B7%E4%B8%8D%E8%A6%81%E5%9C%A8%E8%B4%9F%E6%9D%83%E5%9B%BE%E4%B8%AD%E7%86%9F%E7%BB%83%E7
原题链接 https://codeforces.com/contest/1406/problem/D 思路 样例中a=2,-1,7,3; 差分为-3,8,-4; 设(b[1]=x)+(c[1]=y)=a[1]; ∵b[1]=c[2]>=…>=c[n] x+(y-3)=(x-1)+(y-2)=(x+1)+(y-4)=…=a[2] ∴b[2]=x c[2]=y-3为最优解 其他的解都会导致b[n]或者c[1]变大 使最后答案不是最小 即:差分>0时,将差分的
络谷 P1962 斐波那契数列
络谷 P3379 [模板] 最近公共祖先 LCA 欧拉序+线段树 int cnt; int dep[maxn]; int eoo[maxn]; int ooe[maxn << 1]; void dfs_ooe(int u, int f) { dep[u] = dep[f] + 1; ooe[++cnt] = u; eoo[u] = cnt; for (int i = head[u]; ~i; i = edge[i].nxt) { int v = edge[i].v; if (f ==
题解 [该代码需要配合线段树] int cnt; int fa[maxn]; int dep[maxn]; int siz[maxn]; int son[maxn]; int rk[maxn]; int top[maxn]; int id[maxn]; inline void init_tree() { cnt = 0; } void dfs_ss(int u) { int ms = -1; int mss = 0; siz[u] = 1; for (int i = head[u]; ~i; i
#ifdef __cpp_if_constexpr template <typename T, typename… Args> void read(T& x, Args&… r) { if constexpr (is_integral_v<T> && !is_same_v<decay_t<T>, char>) { x = 0; lli f = 1; char ch = getchar(); while (!i
条款 01:视 C++ 为一个语言联邦 C++分为:C部分、对象C++部分、模板C++部分、STL部分。 条款 02:尽量以 const、enum、inline 替换 #define const: 表示修饰的内容不可更改。 enum: 本质是 int 类型。 inline: 在 class 内时,如果函数允许,他被自动启用。 条款 03:尽可能使用 const 这有利于编译器更好的优化程序,并且让客户减少误操作。 在函数传值时,对于自定义类型,最好使用 const 引用。 用 mutable 修
放在代码的最前面,感受性能加速吧!
#include <cstdio> #include <cstring> using namespace std; const int MOD = 1e4; const int MAXN = 12; struct Mat { long long mat[MAXN][MAXN]; int n, m; Mat operator * (const Mat &b) const { Mat a = *this; Mat ans; ans.n = a.n; ans.m = b
dfs(数的最后若干位,各种限制条件,当前第几位) if 最后一位 return 各种限制条件下的返回值 局部变量 ct=当前位的数字 局部变量 sum=0; for i=0 to ct-1 sum+=当前位取i时一定无无限制的合法状态数 sum+=当前位取i时满足当前限制的合法状态数 根据ct更新限制条件 不再满足则return sum return sum+dfs(当前位后的若干位,更新后的限制条件,下一位) slv(当前数) if(只有一位) return 对应的贡献 局部变量 ct; f
原型 typedef struct _D3DPRESENT_PARAMETERS_ { UINT BackBufferWidth; UINT BackBufferHeight; D3DFORMAT BackBufferFormat; UINT BackBufferCount; D3DMULTISAMPLE_TYPE MultiSampleType; DWORD MultiSampleQuality; D3DSWAPEFFECT SwapEffect; HWND hDeviceWindow; BO
准备 下载源码 下载地址:http://www.wxwidgets.org/downloads/ 选择 Source Code > Windows 7z 下载 解压源码 解压 wxWidgets 编译源码 用 V S打开 wxWidgets-X.X.X\build\msw\wx_vc15.sln 分别选择Debug、DLL Debug、DLL Release、Release 然后点击 生成 > 生成解决方案 等待编译完成即可 样例 准备 新建一个空项目,建立 Main.cpp,复制官
源文件头部注释 列出:版权、作者、编写日期和描述。 每行不要超过80个字符的宽度。 示例: /************************************************* Copyright:Call_Me_Why Author:why Date:2010-08-25 Description:Something about C++ **************************************************/ 函数头部注释 列出:函数的目的/功能、输
题目链接