最近发现了llms.txt这个新东西。它就像是专门给AI看的“网站说明书”。为了给自己的博客配上标准规范的llms.txt,我试了好多WordPress插件都不满意,格式太乱。干脆自己动手写了一个,把页面、文章的分类和摘要都利用起来,让AI能更准确地抓取内容。算是为网站跟上AI潮流做了一点小努力。
普通视图
让网站对 AI 更友好:一次关于 llms.txt 的探索与插件开发
给WordPress添加评论者等级功能
我给博客加了个评论者等级的小功能,主要是想让常来留言的博友有点身份感,也能激励大家多互动。实现方式其实挺简单的,就是根据邮箱统计评论数,分区间定等级,再配上武侠风的称号和颜色。既好看,又带点江湖味儿,让评论区更热闹。
标点符号的用法与中英数字混排
写这篇纯粹是因为我自己的「强迫症」——每次发博客时总要纠结标点符号用对没、中英文数字混在一起时格式乱不乱。作为设计从业者,看不得排版乱七八糟,直接影响内容的阅读体验。于是整理一篇指南,既给自己当规范,也分享给同样被这些细节困扰的小伙伴们。
标点符号
- 整句为中文,应采取全宽(全角:占一个汉字宽度)标点符号。
- 整句为英文,应采取半宽(半角:占半个汉字宽度)标点符号。
- 中英混排时:
- 中文句子内夹用完整英文句子或语段时,保留英文内部标点符号,并用中文引号、括号等包裹。
- 夹用英文单词或词组时,整体使用中文全宽标点符号;但英文专有名称(如 Harvard University, USA.)、标题、数学公式、化学式、计量单位符号、特殊符号(如 @、#)和代码等除外。
点号
点号的作用是点断,主要表示停顿和语气。
- 句末点号:表示句末停顿和句子的语气。包括句号、间号、叹号。
- 句内点号:表示句内各种不同性质的停顿。包括逗号、顿号、分号、冒号。
点号不能出现在一行的开头。
句号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | ||
|---|---|---|---|---|---|
| 中文句号 | 全宽 | 。 | 中文输入法 | . | 用于中文句子结尾 |
| 英文句号 | 半宽 | . | 英文输入法 | . | 用于英文句子结尾或小数点 |
中文科技文献中的「句号」多使用「.」替代「。」,以避免同拉丁字母「o」或数字「0」混淆。
逗号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | ||
|---|---|---|---|---|---|
| 中文逗号 | 全宽 | , | 中文输入法 | , | 中文句子内停顿 |
| 英文逗号 | 半宽 | , | 英文输入法 | , | 英文句子内停顿或分隔列表 |
注意避免「一逗到底」,即整个段落除了结尾,全部停顿都使用逗号,这样的语段理解难度是极高的。
逗号,连接句子,顿号,连接并列词语,主要是短促的词语,分号,用来表示复句的并列关系,一般情况下,分号不会单独存在。
逗号,连接句子。顿号,连接并列词语,主要是短促的词语。分号,用来表示复句的并列关系。一般情况下,分号不会单独存在。
顿号
顿号是中文特有标点。
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | ||
|---|---|---|---|---|---|
| 中文顿号 | 全宽 | 、 | 中文输入法 | \ | 用于并列词语间的短停顿 |
| 英文不使用顿号,通过英文逗号实现中文顿号的功能 | |||||
中文句子内部的并列词,应该用全宽顿号分隔,而不用逗号,即使并列词是英语也是如此。
我最欣赏的科技公司有 Google,Apple,字节跳动和阿里巴巴等。
我最欣赏的科技公司有 Google、Apple、字节跳动和阿里巴巴等。
英文句子中,并列词语之间使用半宽逗号(,)分隔。
Microsoft Office includes Word、Excel、PowerPoint、Outlook and other components.
Microsoft Office includes Word, Excel, PowerPoint, Outlook and other components.
冒号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | ||
|---|---|---|---|---|---|
| 中文冒号 | 全宽 | : | 中文输入法 | Shift + ; | 用于中文语境下引出解释和说明 |
| 英文冒号 | 半宽 | : | 英文输入法 | Shift + ; | 用于英文句子的解释、说明或时间表示 |
表示时间时,应使用半宽冒号(:)。
早上 8:05
早上 8:05
分号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | ||
|---|---|---|---|---|---|
| 中文分号 | 全宽 | ; | 中文输入法 | ; | 用于中文复句中并列分句的停顿 |
| 英文分号 | 半宽 | ; | 英文输入法 | ; | 用于英文中连接相关独立子句或复杂列表项 |
中文句子内夹用英文句子或语段,保留该英文句子或语段内部的英文分号。
推开面试室的门时,他忽然记起祖父那句话:「Try, and you still have a chance; give up, and you shall have nothing.」。
中文句子内夹用英文单词或词组,使用中文分号。
这位老人的真实想法谁也猜不透:表示同意,他用 maybe;表示不同意,他还是用 maybe。
叹号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | ||
|---|---|---|---|---|---|
| 中文叹号 | 全宽 | ! | 中文输入法 | Shift + 1 | 用于标示中文句子的感叹语气 |
| 英文叹号 | 半宽 | ! | 英文输入法 | Shift + 1 | 用于标示英文句子的感叹语气 |
中文句子中,叹号叠用不应超过三个。
不可思议!!!!!!
不可思议!!!
英文句子中,叹号不可叠用。
This is unbelievable!!!
This is unbelievable!
问号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | ||
|---|---|---|---|---|---|
| 中文问号 | 全宽 | ? | 中文输入法 | Shift + / | 用于标示中文句子的疑问语气 |
| 英文问号 | 半宽 | ? | 英文输入法 | Shift + / | 用于标示英文句子的疑问语气 |
问号也有标号的用法,即用于句内,表示存疑或不详。
钟蝶(?—518),川长社人,南朝梁代文学批评家。
Zhong Die (?–518), native of Chuanchangshe, was a Liang dynasty (Southern Dynasties) literary critic.
中文句子中,问号叠用不应超过三个,如「???」;英文句子中,问号不可叠用。
中文句子中,问号和叹号同时使用时,问号在前,叹号在后;英文句子中,问号和叹号不可同时使用。
真的!?
Really?!
真的?!
Really?
标号
标号的作用是标明,主要标示某些成分(主要是词语)的特定性质和作用。
- 夹注型:包括引号、括号、书名号。
- 非夹注型:包括破折号、省略号、连接号、间隔号、分隔号。
- 引号、括号、书名号的前半部分不能出现在行尾,后半部分不能出现在行首。
- 省略号、连接号、间隔号不能出现在行首。
- 分隔号首尾都不能出现。
引号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | |||
|---|---|---|---|---|---|---|
| 中文 | 单直角引号 | 全宽 | 「 」 | 中文输入法 | Shift + [ / ] | 用于标示中文句子中的引用、强调或特殊含义 |
| 双直角引号 | 『 』 | 在输入法符号面板中查找 | 用于中文引号内的二次引用或特殊强调 | |||
| 英文 | 双引号 | 半宽 | " " | 英文输入法 | Shift + ' | 用于标示英文句子中的引用、强调或特殊含义 |
| 单引号 | ' ' | ' | 用于英文引号内的二次引用或特殊强调 | |||
- 中文采用「单双交替」的引号嵌套规则,即「『「『』」』」;
- 英文采用「双单交替」的引号嵌套规则,即 " ' " ' ' " ' "。
他批评道:「某些人鼓吹『『躺平』是自由』,这种价值观根本是『『逃避』的借口』。」
The editor noted, "The author argued, 'Critics misread the phrase ‘‘Life’ is a borrowed gift’ as nihilistic.'"
他批评道:「某些人鼓吹『「躺平」是自由』,这种价值观根本是『「逃避」的借口』。」
The editor noted, "The author argued, 'Critics misread the phrase "‘Life’ is a borrowed gift" as nihilistic.'"
在有多个独立成段的引文时,应该只在每段开头使用前引号,并且在最后一段结尾使用后引号。
他说:
「天生我材必有用,千金散尽还复来。」
「仰天大笑出门去,我辈岂是蓬蒿人。」
「抽刀断水水更流,举杯消愁愁更愁。」
他说:
「天生我材必有用,千金散尽还复来。
「仰天大笑出门去,我辈岂是蓬蒿人。
「抽刀断水水更流,举杯消愁愁更愁。」
括号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | |||
|---|---|---|---|---|---|---|
| 中文 | 圆括号 | 全宽 | ( ) | 中文输入法 | Shift + 9 / 0 | 补充说明、注释、解释 |
| 方括号 | [ ] | 在输入法符号面板中查找 | 标识国籍 | |||
| 六角括号 | 〔 〕 | 在输入法符号面板中查找 | 标示所属朝代或公文发文字号中的发文年份 | |||
| 方头括号 | 【 】 | [ / ] | 标示被注释的词语 | |||
| 空心方头括号 | 〖 〗 | 在输入法符号面板中查找 | 作为二级标注符号使用 | |||
| 英文 | 圆括号 | 半宽 | ( ) | 英文输入法 | Shift + 9 / 0 | 补充说明、注释、解释 |
| 方括号 | [ ] | [ / ] | 引用补充、编辑修改 | |||
| 花括号 | { } | Shift + [ / ] | 编程、数学、集合 | |||
| 尖括号 | < > | Shift + , / . | 编程 | |||
除科技书刊中的数学、逻辑公式外,所有括号(特别是同一形式的括号)应尽量避免套用。必须套用括号时,宜采用不同的括号形式配合使用。
〔茸(róng)毛〕很细很细的毛。
中文夹用英文注释,用中文全宽圆括号标示注释。
The Beatles 有一首歌,题为《除了我和我的猴子人人都想捂藏一点东西》(Everybody's Got Something to Hide except Me and My Monkey),这首歌后来音乐家称之为《猴子》。
The Beatles 有一首歌,题为《除了我和我的猴子人人都想捂藏一点东西》(Everybody's Got Something to Hide except Me and My Monkey),这首歌后来音乐家称之为《猴子》。
书名号
书名号是中文特有标点。
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | |||
|---|---|---|---|---|---|---|
| 中文 | 双书名号 | 全宽 | 《 》 | 中文输入法 | Shift + < / > | 用于中文正式出版物名称(主书名号) |
| 单书名号 | 〈 〉 | 在输入法符号面板中查找 | 用于书名号内的嵌套或次级作品名称 | |||
| 英文不使用书名号,以英文斜体字表示 | ||||||
标有引号、书名号的并列词语,分隔已经非常清晰,所以它们之间不需要再增加标点符号进行分隔了。
《三国演义》、《西游记》、《水浒传》、《红楼梦》并称四大名著。
《三国演义》《西游记》《水浒传》《红楼梦》并称四大名著。
但如果有更多符号穿插其中,比如书名号之后有括注,阅读起来就会十分混乱,所以这时就要用合适的符号进行连接和分割。
《三国演义》(罗贯中著)《西游记》(吴承恩著)《水浒传》(施耐庵著)《红楼梦》(曹雪芹著)并称四大名著。
《三国演义》(罗贯中著)、《西游记》(吴承恩著)、《水浒传》(施耐庵著)、《红楼梦》(曹雪芹著)并称四大名著。
书名号采用「双单交替」的嵌套规则,即《〈《〈〉》〉》。
〈某某集团关于下发《〈《子公司安全生产管理办法》修订版〉执行细则》的通知〉
《某某集团关于下发〈《〈子公司安全生产管理办法〉修订版》执行细则〉的通知》
中文句子中夹有英文书籍名、报刊名时,不能借用中文书名号,而应以英文斜体字表示。英文文章的标题用引号标示。
The Evening Post 发表了这篇评论,但把标题改成了「What We Eat Tomorrow?」。
破折号
表示语气或声音的延续、语意的转换或行文的补充。
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | ||
|---|---|---|---|---|---|
| 中文破折号 | 全宽 占两个汉字宽度 | —— | 中文输入法 | Shift + - | 用于标示中文语气或声音的延续、语意的转换或行文的补充 |
| 英文破折号 | 长度相当于字母 n | – | 英文输入法 | Alt + 0150(数字键盘) | 用于标示数值范围、事物之间的关系等 |
| 长度相当于字母 m | — | Alt + 0151(数字键盘) | 用于标示语流的间断、插人、附加说明等 | ||
省略号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | ||
|---|---|---|---|---|---|
| 中文省略号 | 全宽 占两个汉字宽度 | …… | 中文输入法 | Shift + 6 | 用于标示中文内容的省略、语意未尽或语气的不连续 |
| 英文省略号 | 全宽 | … | 英文输入法 | Alt + 0133(数字键盘) | 用于标示英文内容的省略、语意未尽或语气的不连续 |
中文省略号不应与「等」这个词一起使用。
我们为会餐准备了香蕉、苹果、梨⋯⋯等各色水果。
我们为会餐准备了各色水果,有香蕉、苹果、梨⋯⋯
我们为会餐准备了香蕉、苹果、梨等各色水果。
英文句子中省略号使用全宽省略号(…)分隔。
Juan thought and thought ... and then thought some more.
Juan thought and thought…and then thought some more.
Juan thought and thought … and then thought some more.
连接号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | |||
|---|---|---|---|---|---|---|
| 中文连接号 | 短横线 | 半宽 | – | 中文输入法 | Alt + 0150(数字键盘) | 化合物的名称或表格、插图的编号、产品型号; 连接号码,包括门牌号码、电话号码,以及用阿拉伯数字表示年月日等; 在复合名词中起连接作用; 汉语拼音、外来语内部的分合。 |
| 一字线 | 全宽 | — | Alt + 0151(数字键盘) | 标示相关项目(如时间、地域等)的起止 | ||
| 浪纹线 | ~ | 在输入法符号面板中查找 | 标示数值范围的起止 | |||
| 英文连接号 | 即连字符 | 长度相当于字母 m 的 1/3 | - | 英文输入法 | - | 连接单词以构成复合词; 在行文移行时分隔音节; 构成分数和部分数字。 |
短横线的用法示例:
3–戊酮为无色液体,对眼及皮肤有强烈刺爱性
参见下页表 2–8、表 2–9
安宁里东路 26 号院 3–2–11 室
联系电话:010-88842603
2025–06–11
吐鲁番–哈密盆地
WZ–10 直升机具有复杂天气和夜间作战的能力。
shuōshuō–xiàoxiào(说说笑笑)
盎格鲁–撒克逊人
让–雅克·卢梭
一字线的用法示例:
沈括(1031一1095),宋朝人。
2025 年 6 月 9 日一2025 年 6 月 12 日
北京一上海特别旅客快车
浪纹线的用法示例:
25~30 g
第五~八课
间隔号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | ||
|---|---|---|---|---|---|
| 中文间隔号 | 半宽 | · | 中文输入法 | ` 或 Alt + 0183(数字键盘) | 外国人名中文译名、少数民族音译名; 标识书名与篇、章、卷之间的分界; 以月、日为标志的事件或节日。 |
| 英文间隔号 | 英文输入法 | Alt + 0183(数字键盘) | 姓名缩写 术语并列 语言学 | ||
比尔·盖茨
《沁园春·雪》
「3·15」消费者权益日
当外语人名缩写成一个字母时,其后宜使用西文句点,而非中文间隔号。
B·盖茨
B. 盖茨
分隔号
| 标点类型 | 符号形式 | Windows 输入方式 | 使用场景 | ||
|---|---|---|---|---|---|
| 中文分隔号 | 半宽 | / | 中文输入法 | / | 分隔诗行; 分隔音节节拍; 表示「或」关系; 路径或网址分隔; 分数或日期简写。 |
| 英文分隔号 | 英文输入法 | ||||
半身/对开
3/4
em/en
https://gshuo.space
空格
多空一格
中文与英文之间加空格
通过Google搜索引擎,你可以更快地找到想要的信息。
通过 Google 搜索引擎,你可以更快地找到想要的信息。
专有产品名词,按照官方所定义的格式书写。
豆瓣FM
中文与数字之间加空格
2025年6月17日,「积蒴一掷」发出这篇文章。
2025 年 6 月 17 日,「积蒴一掷」发出这篇文章。
数字与单位之间加空格
2kg
2 kg
数字与运算符之间加空格
20±2%
p<0.01
1+1=2
20 ± 2%
p < 0.01
1 + 1 = 2
不必空格
货币符号与数字之间不必空格
¥ 10
¥10
英文的货币名称,建议参考国际标准 ISO 4217。
百分号与数字之间不必空格
百分号(%)不是单位,因此应该紧挨在数字后面。
5 %
5%
倍数与单位之间不必空格
2 x
3 n
2x
3n
数字
- 优先阿拉伯数字:统计数据、日期、计量单位等。
- 优先中文数字:传统表达、文学修辞、法律文书。
阿拉伯数字
一律使用半宽形式,不得使用全宽形式。
1234567890
1234567890
千分撇
为方便阅读,整数部分超四位以上的阿拉伯数字,应添加半宽字符千分撇(,)。整数部分向左每三位一节,小数部分不分节。
100,000,0
0.000,1
1,000,000
0.0001
对于四位的数值,千分撇是选用的,比如「1000」和「1,000」都可以接受。
1000
1,000
数值范围
表示数值范围时,用浪纹线(~)连接。前后两个数值的附加符号或计量单位相同时,在不造成歧义的情况下,前一个数值的附加符号或计量单位可省略,如果省略数值的附加符号或计量单位会造成歧义,则不应省略。
13~17 万元
15~30%
13 万元~17 万元
15%~30%
-36~-8 ℃
10 × 15 × 20 m
参考资料
使用原子 TAS 指令实现自旋锁
使用原子 TAS 指令实现自旋锁
使用原子 TAS 指令实现自旋锁 Implementing a Spinlock Using the Atomic TAS Instruction 从零实现自旋锁:基于 TAS 的最小同步原语 Building a Spinlock from Scratch with Atomic TAS 用 test-and-set 实现最简单的互斥锁 Implementing a Minimal Mutex Using Test-and-Set 自旋锁的底层原理:TAS、原子性与忙等待 Inside Spinlocks: TAS, Atomicity, and Busy Waiting 原子操作与自旋锁:用 C 语言实现线程同步 Atomic Operations and Spinlocks: Thread Synchronization in C 从原子指令到锁:全面理解 TAS 和自旋锁 From Atomic Instructions to Locks: A Complete Guide to TAS and Spinlocks 动手写一个自旋锁:tryLock / lockAcquire / lockRelease 全实现 Hands-On Spinlock Implementation: tryLock, lockAcquire, and lockRelease 你的第一个自旋锁:基于 C 语言的 TAS 实现 Your First Spinlock: A TAS-Based Implementation in C 原子交换与线程互斥:自旋锁实现指南 Atomic Exchange and Thread Mutual Exclusion: A Guide to Implementing Spinlocks假设我们有一个 TAS(Take-And-Set)函数。该操作返回内存中原来的值,并以原子方式将其替换为新值。原子性(atomicity)意味着没有其他线程能够观察到中间状态;整个读-写操作是一体不可分的。 在 C++ 中,标准库函数
std::exchange 在逻辑上表现相同,但它不是原子操作。同步原语需要硬件级别的原子性。
int TAS(int* memory, int newVal) {
int old = *memory;
*memory = newVal;
return old;
}
我们想使用这个原语来实现一个简单的自旋锁,包括:
lockAcquire()lockRelease()
typedef struct {
int lock;
} lockType;
typedef struct {
int val;
} threadArgType;
void threadFunc(void* arg) {
lockAcquire((static_cast<lockType*>arg)->lock);
(static_cast<threadArgType*>arg)->val++;
lockRelease((static_cast<lockType*>arg)->lock);
}
实现 tryLock
tryLock 函数尝试获取锁一次。如果锁为空(值为 0),TAS 将其设置为 1 并返回原值(0)。如果锁已被占用,TAS 返回 1。tryLock 函数是非阻塞的——它会立即返回。
因此 tryLock() 只有在 TAS 返回 0 时才会成功:
enum {
UNLOCKED = 0,
LOCKED = 1
}
int tryLock(lockType* lock) {
// 如果之前已锁定返回 1,如果之前未锁定返回 0
int old = TAS(lock->lock, LOCKED);
return (old == UNLOCKED); // true (1) = 成功获取锁
}
实现 lockAcquire()
普通的锁获取应当“自旋”直到 tryLock() 成功。这称为 自旋锁,因为 CPU 会忙等待。必要时可以加入短暂的 sleep。例如,sleep(0) 并不会真正暂停执行,而是让出 CPU,允许其他线程运行。
它通常用于实现跨线程的互斥自旋锁。
void lockAcquire(lockType* lock) {
while (!tryLock(lockType* lock)) {
// 自旋直到锁可用
}
}
另一种实现:
void lockAcquire(lockType* lock) {
do {
if (tryLock(lockType* lock)) {
break;
}
} while (1);
}
展开 tryLock:
void lockAcquire(lockType* lock) {
do {
int old = TAS(lock->lock, LOCKED);
// 无论锁是否已被获取,锁都已设置为 LOCKED
if (old == UNLOCKED) {
break;
}
} while (1);
}
这是使用 TAS 实现的最简单方法。在实际系统中,我们可能会加入 pause 指令或退避策略,但基本思路是相同的。
实现 lockRelease()
释放锁时,持有者只需将锁变量写为 0。由于 TAS 是“设置新值并返回旧值”,它同样适用于释放锁:
void lockRelease(lockType* lock) {
TAS(lock->lock, UNLOCKED);
}
或者使用简单的原子存储也足够,但由于 TAS 是我们唯一的工具,我们重用它。请注意,在这里重复释放锁是安全的,因为再次将其设置为 UNLOCKED=0 不会产生副作用。
总结
仅使用原子 TAS 指令,我们实现了:- 一个
tryLock()尝试 - 一个
lockAcquire()自旋锁 - 一个
lockRelease()解锁操作
相关文章:
- 简易教程: C++的智能指针 C++ 智能指针教程 C++ 中的智能指针提供了自动且安全的内存管理。它们通过 RAII(资源获取即初始化)机制,帮助开发者避免内存泄漏和悬空指针的问题,确保对象在生命周期结束时被正确释放。 本教程将介绍 C++ 中三种主要的智能指针: std::unique_ptr:独占式所有权 std::shared_ptr:共享式所有权 std::weak_ptr:非拥有式弱引用 1. std::unique_ptr unique_ptr 拥有独占所有权。一个资源只能被一个...
- C++中的 const和constexpr 比较 C++ const 与 constexpr:真正的区别是什么? 一眼看都是定义常量。 为什么这很重要 现代 C++ 鼓励编写不可变、高效且表达力强的代码。两个关键字—const 和 constexpr—是这一理念的核心。它们看起来很相似,但理解它们的不同语义,对于正确利用编译期与运行期行为至关重要。 高层次对比 特性 const constexpr...
- 被动收入之: 微博红包 今年开始重新经营我的微博帐号 drlai 收到两笔微信红包,应该是来自于官方的支持,150元(成功提现到支付宝)。虽然这不能持久,也没多少,但毕竟实现了零的突破,意义重大。 如果流量上来,内容创作者可能会接受到比较多的赞赏,这也是一个比较简单的变现方法。这也能作为一种被动收入,不过如果不是头部网红,可能杯水车薪,但如果你有好几个类似这样的,也能积少成多! 在用户中心,微博用户可以每天登陆手机微博APP打卡,获取点数和少量的红包钱(几分钱),积少成多! 微博做些小任务可获得积分和几分钱。聊胜于无。 微博的主要盈利模式 微博的主要盈利模式主要包括以下几个方面: 广告收入:微博的大部分收入来源于广告,尤其是品牌广告和效果广告。广告形式包括信息流广告(类似于推文广告)、热门话题广告、开屏广告和视频广告。品牌和企业可以利用微博庞大的用户群和社交互动来提升曝光率、推广品牌和产品。 会员服务:微博提供的VIP会员服务,用户可以支付订阅费用来享受更多的特权,比如个性化的主题、特有的表情包、私密权限设置等。这些会员服务主要面向个人用户,提升其社交体验。 直播和打赏:微博提供直播平台,用户可以通过购买虚拟礼物来支持主播,微博会从这些打赏中抽取一定比例的分成。此外,微博与内容创作者分成,通过内容付费、知识付费等形式变现。 增值服务:针对企业和大V(拥有大量粉丝的用户),微博还提供增值服务,如账号认证、粉丝数据分析、精准推送、推广和营销工具等。这些服务帮助企业提升营销效果,同时也增加了微博的收入来源。 电商和导流:微博上有大量的电商导流业务,尤其是和明星、网红的合作推广。微博用户在浏览社交内容时,可以直接跳转到商品购买链接,微博通过这种方式赚取导流佣金。 游戏联运:微博也会与一些游戏公司合作推出联合运营的游戏,微博负责推广和流量引入,用户充值或付费时,微博可以获得一部分的分成。 这些模式相结合,使得微博能够在广告市场、内容创作和电商等多个领域获利。...
- 借助AI快速开源了N个小工具: 写代码越来越像做产品了, AI 真把我宠坏了(Vibe Coding) 程序员的未来?Vibe Coding + AI 一起上! 借助 AI 快速开源了三个小工具 最近,我利用 ChatGPT-4o 和 o4-mini 快速开发并开源了几个小工具。起因其实很简单——每次想转换 YAML/JSON 或进行...
- 豪车的修理费用就是贵一些 去年买了保时捷卡宴SUV(Porsche Cayenne)后,我一直担心将来修车费用会很高。当时购车时,车厂做了一次全面保养,把车里里外外都清洁了一遍。虽然这辆车已经三年车龄,但看上去几乎和新车没区别。 在英国,三年以内的新车通常不需要做MOT年检。而且很多这类新车会通过PCP(个人合同购车)方式出租给车主。简单来说,就是车主每月支付一笔租金,租期通常为三年,期满后可以选择一次性付清尾款买下车辆,也可以继续换租一辆新车。 举个例子,如果一辆新车售价是10万英镑,车厂可能按未来三年折旧后的50%残值来计算每月租金。三年后,如果车主不想买断,车厂就会将车辆作为二手车卖出,回收那5万英镑的残值。这样一来,车厂基本不会亏钱。此外,PCP合同中还有附加条款,比如每年限行1万英里,超出的部分需要额外付费,这些内容都会写在合同里。 车龄到了三年,车辆需要首次做MOT年检,同时车辆的市场价值也会首次出现较大幅度的贬值(一般是50%,甚至更多)。修车厂老板告诉我,相比玛莎拉蒂等其他豪车,保时捷的保值率相对较高。 这一年我开这辆保时捷基本没出什么问题。今年年初做了年检,顺利通过。随后又做了一次常规保养,修车厂老板告诉我,前后刹车片已经磨损了80%–85%。我们住剑桥村里,开车比较多(上班、送娃、家庭旅游都要用车),一年大概能开1-2万英理。 几周后我将车送回去更换刹车片。修完后账单是将近900英镑。我觉得有点贵,车行老板解释说,不仅换了前后刹车片,还有一个前雷达的传感器掉进了车体内部,为了修这个传感器需要拆掉前保险杠等部件,花了6个小时人工费。 我当时质疑说为啥这次修这么贵,他说:“因为这是保时捷。”我说:“那和别的车有什么区别?”他说:“It is not the same.” 我说不都一样么,他说:“It is not...
- 重要通知: 弃用 FeedBurner RSS 请改用 https://justyy.com/feed 最近我发现原本的 RSS(/rss、/feed)没有按时更新。 进一步检查后发现这些地址都被 301 重定向到了 FeedBurner(https://feeds.feedburner.com/zhihua-xblog),而 FeedBurner 已经久未维护,偶有抓取失败或延迟,导致读者无法及时收到新文章。 造成这次重定向的原因是我们使用的第三方主题/插件(mytheme)里曾经内置了将站点 feed 转发到 FeedBurner 的功能。 当时之所以做 301...
- 换了个奥迪Q5大灯花了我1000英镑 我那辆奥迪Q5 SUV今年年检没通过,原因是左前车灯坏了,需要更换。车厂告诉我,光是订购零件就要700多英镑,加上人工费,总费用得1000英镑。但没办法,如果不修,车辆年检(MOT)就过不了,车也不能上路。 MOT是英国的机动车强制性安全检测(Ministry of Transport Test)的简称。 近侧前位置灯不工作 drl/位置灯集成(4.2.1(a)(ii)) Nearside Front Position lamp not working drl/position...
- 你给SteemIt中文微信群拖后腿了么? 这年头不缺算法, 就缺数据. 这两天花了很多时间在整API上, 整完之后自己用了一下还觉得真是挺方便的. 今天就突然想看一看自己是否给大家拖后腿了, 于是调用每日中文区微信群排行榜单的API, 刷刷拿着 NodeJs 练手: // @justyy var request = require("request")...
C++中检测编译时与运行时: if consteval 与 std::is_constant_evaluated()
C++ 一直在不断增加新特性,以便程序员能够区分在编译时运行的代码和在运行时执行的代码。其中两个重要工具是函数 std::is_constant_evaluated()(C++20)和语言级别的 if consteval(C++23)。本文将解释这两者,展示实际示例,比较它们的保证和权衡,并建议在何时使用各自的方法。
这两种技术都允许你编写分支,根据当前的求值是在常量求值(编译时)上下文中还是运行时上下文中而表现不同。差异虽然细微,但非常重要:一个是返回布尔值的函数,另一个是编译器视为仅在编译时检查的特殊 if 语句,编译器会进行特殊处理。
std::is_constant_evaluated() (C++20)
这是一个在 <type_traits> 中声明的函数:
#include <type_traits>
constexpr bool std::is_constant_evaluated() noexcept;
当当前表达式在常量表达式(编译时)上下文中求值时,该函数返回 true,否则返回 false。
示例:
#include <iostream>
#include <type_traits>
constexpr int f() {
if (std::is_constant_evaluated()) {
return 42; // 编译时
} else {
return 0; // 运行时
}
}
int main() {
constexpr int a = f(); // 编译时求值 -> 42
int b = f(); // 运行时求值 -> 0
std::cout << a << ", " << b << "\n"; // 打印 "42, 0"
}
if consteval (C++23)
if consteval 是一个语言级别的 if 条件语句,编译器用它来判断当前求值上下文是否为常量求值。它提供了更强的编译时保证:编译器知道 consteval 分支在常量求值中必须可用,并且会拒绝不能在该上下文中出现的代码。 语法:
if consteval {
// 仅编译时代码
} else {
// 仅运行时代码
}
示例:
#include <iostream>
constexpr int f() {
if consteval {
return 42; // 编译时版本
} else {
return 0; // 运行时版本
}
}
int main() {
constexpr int a = f(); // 编译时上下文 -> 返回 42
int b = f(); // 运行时上下文 -> 返回 0
std::cout << a << ", " << b << "\n"; // 打印 "42, 0"
}
主要区别(总结)
- 形式: std::is_constant_evaluated() 是一个函数;if consteval 是一个语言级条件语句。
- 标准: std::is_constant_evaluated() 出现在 C++20 中;if consteval 出现在 C++23 中。
- 保证: if consteval 为编译器提供编译时保证,并拒绝编译时无法使用的 consteval 分支中的代码。 std::is_constant_evaluated() 的执行环境更为宽松:它返回布尔值,但不会强制编译器拒绝其他分支中无效的编译时构造。
- 在表达式内部使用: std::is_constant_evaluated() 可以在语句形式的 if 无法使用的表达式内部使用(例如,在三元运算符内部)。if consteval 需要语句级上下文。
具体比较示例
两个函数看起来相似,但在执行方面表现不同:
// if-consteval 示例
constexpr int f() {
if consteval {
return 1; // 仅在编译时
} else {
return 2; // 仅限运行时
}
}
// std::is_constant_evaluated() 示例
#include <type_traits>
constexpr int g() {
if (std::is_constant_evaluated()) {
return 1; // 可能仍会编译运行时路径
} else {
return 2;
}
}
以下场景中,差异至关重要:
// 使用 if consteval 时,编译器将拒绝无效的仅限编译时构造
constexpr int bad() {
if consteval {
std::cout << "compile-time"; // ❌ 错误 — 常量求值中不允许 I/O
}
return 0;
}
// 使用 std::is_constant_evaluated() 时,编译器会更加宽容,可能会编译通过,直到代码
// 实际用于常量表达式上下文。
#include <type_traits>
constexpr int perhaps_bad() {
if (std::is_constant_evaluated()) {
std::cout << "compile-time"; // 可能会编译通过;只有在 const-expr 中求值时才会出现错误
}
return 0;
}
使用场景
- 如果您的目标是 C++23(或更高版本),并且想要清晰的、编译时强制的分支:请优先使用
if consteval。 - 如果您必须仅支持 C++20 环境:请使用
std::is_constant_evaluated()。 - 如果您需要在表达式(而非语句)中进行检查,请使用
std::is_constant_evaluated(),因为if consteval是语句级的。 - 如果您希望编译器拒绝编译时无法使用的代码,
if consteval可以提供更强的保证。
实际用例
- 为编译时和运行时(快速预计算 vs 较慢的运行时)编写不同的实现逻辑)。
- 保护仅运行时操作(例如 I/O、动态分配或系统调用),以免它们被意外地用于常量求值路径。
- 在编写可在 constexpr 上下文和正常运行时上下文中使用的库时,提供更清晰、更能揭示意图的代码。
简短实用的检查清单
- 需要表达式级检查?→
std::is_constant_evaluated()。 - 想要编译器强制执行的仅编译时分支?→
if consteval。 - 仅针对 C++20?→
std::is_constant_evaluated()。 - 针对 C++23+ 并更注重清晰度和安全性? →
if consteval.
TL;DR
std::is_constant_evaluated() — C++20:在编译时求值中返回 true 的函数(适用于表达式级检查)。 if consteval — C++23:- 编译器将其视为仅编译时分支的语言级条件语句;
- 更强的编译时执行力和更清晰的意图。
结束语
这两个工具都很有用。如果您可以使用 C++23,则最好使用if consteval 以获得更清晰的语义和更强的编译时保证,并在与 C++20 兼容或需要表达式级检查时回退到 std::is_constant_evaluated()
[show_file file="/var/www/wp-post-common/justyy.com/cpp.php"]
英文:Detecting Compile-time vs Runtime in C++: if consteval vs std::is_constant_evaluated()相关文章:
- 简易教程: C++的智能指针 C++ 智能指针教程 C++ 中的智能指针提供了自动且安全的内存管理。它们通过 RAII(资源获取即初始化)机制,帮助开发者避免内存泄漏和悬空指针的问题,确保对象在生命周期结束时被正确释放。 本教程将介绍 C++ 中三种主要的智能指针: std::unique_ptr:独占式所有权 std::shared_ptr:共享式所有权 std::weak_ptr:非拥有式弱引用 1. std::unique_ptr unique_ptr 拥有独占所有权。一个资源只能被一个...
- C++中的 const和constexpr 比较 C++ const 与 constexpr:真正的区别是什么? 一眼看都是定义常量。 为什么这很重要 现代 C++ 鼓励编写不可变、高效且表达力强的代码。两个关键字—const 和 constexpr—是这一理念的核心。它们看起来很相似,但理解它们的不同语义,对于正确利用编译期与运行期行为至关重要。 高层次对比 特性 const constexpr...
- 借助AI快速开源了N个小工具: 写代码越来越像做产品了, AI 真把我宠坏了(Vibe Coding) 程序员的未来?Vibe Coding + AI 一起上! 借助 AI 快速开源了三个小工具 最近,我利用 ChatGPT-4o 和 o4-mini 快速开发并开源了几个小工具。起因其实很简单——每次想转换 YAML/JSON 或进行...
- 被动收入之: 微博红包 今年开始重新经营我的微博帐号 drlai 收到两笔微信红包,应该是来自于官方的支持,150元(成功提现到支付宝)。虽然这不能持久,也没多少,但毕竟实现了零的突破,意义重大。 如果流量上来,内容创作者可能会接受到比较多的赞赏,这也是一个比较简单的变现方法。这也能作为一种被动收入,不过如果不是头部网红,可能杯水车薪,但如果你有好几个类似这样的,也能积少成多! 在用户中心,微博用户可以每天登陆手机微博APP打卡,获取点数和少量的红包钱(几分钱),积少成多! 微博做些小任务可获得积分和几分钱。聊胜于无。 微博的主要盈利模式 微博的主要盈利模式主要包括以下几个方面: 广告收入:微博的大部分收入来源于广告,尤其是品牌广告和效果广告。广告形式包括信息流广告(类似于推文广告)、热门话题广告、开屏广告和视频广告。品牌和企业可以利用微博庞大的用户群和社交互动来提升曝光率、推广品牌和产品。 会员服务:微博提供的VIP会员服务,用户可以支付订阅费用来享受更多的特权,比如个性化的主题、特有的表情包、私密权限设置等。这些会员服务主要面向个人用户,提升其社交体验。 直播和打赏:微博提供直播平台,用户可以通过购买虚拟礼物来支持主播,微博会从这些打赏中抽取一定比例的分成。此外,微博与内容创作者分成,通过内容付费、知识付费等形式变现。 增值服务:针对企业和大V(拥有大量粉丝的用户),微博还提供增值服务,如账号认证、粉丝数据分析、精准推送、推广和营销工具等。这些服务帮助企业提升营销效果,同时也增加了微博的收入来源。 电商和导流:微博上有大量的电商导流业务,尤其是和明星、网红的合作推广。微博用户在浏览社交内容时,可以直接跳转到商品购买链接,微博通过这种方式赚取导流佣金。 游戏联运:微博也会与一些游戏公司合作推出联合运营的游戏,微博负责推广和流量引入,用户充值或付费时,微博可以获得一部分的分成。 这些模式相结合,使得微博能够在广告市场、内容创作和电商等多个领域获利。...
- 豪车的修理费用就是贵一些 去年买了保时捷卡宴SUV(Porsche Cayenne)后,我一直担心将来修车费用会很高。当时购车时,车厂做了一次全面保养,把车里里外外都清洁了一遍。虽然这辆车已经三年车龄,但看上去几乎和新车没区别。 在英国,三年以内的新车通常不需要做MOT年检。而且很多这类新车会通过PCP(个人合同购车)方式出租给车主。简单来说,就是车主每月支付一笔租金,租期通常为三年,期满后可以选择一次性付清尾款买下车辆,也可以继续换租一辆新车。 举个例子,如果一辆新车售价是10万英镑,车厂可能按未来三年折旧后的50%残值来计算每月租金。三年后,如果车主不想买断,车厂就会将车辆作为二手车卖出,回收那5万英镑的残值。这样一来,车厂基本不会亏钱。此外,PCP合同中还有附加条款,比如每年限行1万英里,超出的部分需要额外付费,这些内容都会写在合同里。 车龄到了三年,车辆需要首次做MOT年检,同时车辆的市场价值也会首次出现较大幅度的贬值(一般是50%,甚至更多)。修车厂老板告诉我,相比玛莎拉蒂等其他豪车,保时捷的保值率相对较高。 这一年我开这辆保时捷基本没出什么问题。今年年初做了年检,顺利通过。随后又做了一次常规保养,修车厂老板告诉我,前后刹车片已经磨损了80%–85%。我们住剑桥村里,开车比较多(上班、送娃、家庭旅游都要用车),一年大概能开1-2万英理。 几周后我将车送回去更换刹车片。修完后账单是将近900英镑。我觉得有点贵,车行老板解释说,不仅换了前后刹车片,还有一个前雷达的传感器掉进了车体内部,为了修这个传感器需要拆掉前保险杠等部件,花了6个小时人工费。 我当时质疑说为啥这次修这么贵,他说:“因为这是保时捷。”我说:“那和别的车有什么区别?”他说:“It is not the same.” 我说不都一样么,他说:“It is not...
- C++ 教程: 用std::move来移动所有权 📘 C++ 移动语义与 std::move() 教程 C++的std::move用于转移变量/对像的所有权/Ownership。 🔹 什么是移动语义? 在 C++ 中,移动语义通过转移资源所有权/Ownership(如内存或文件句柄)来优化性能,而不是复制它们。 移动语义是在 C++11 中引入的,它允许: 更快速地传递大型或昂贵的对象...
- C++ Ranges 教程 C++20 引入了 ranges(范围),这是一个强大且优雅的抽象,用于处理序列(如数组、vector 等)。相比传统的迭代器或旧式循环,Ranges 提高了代码的可读性、可组合性和性能。 什么是 Range? 在 C++20 中,range(范围) 是一种抽象,代表一个可以迭代的元素序列。它与 views(视图) 和 actions(操作) 如过滤、转换等配合使用非常自然。...
- 换了个奥迪Q5大灯花了我1000英镑 我那辆奥迪Q5 SUV今年年检没通过,原因是左前车灯坏了,需要更换。车厂告诉我,光是订购零件就要700多英镑,加上人工费,总费用得1000英镑。但没办法,如果不修,车辆年检(MOT)就过不了,车也不能上路。 MOT是英国的机动车强制性安全检测(Ministry of Transport Test)的简称。 近侧前位置灯不工作 drl/位置灯集成(4.2.1(a)(ii)) Nearside Front Position lamp not working drl/position...
Mac空格响应慢?Adobe软件Ps、Ai卡在抓手工具解决方法,临时抓手无法恢复指针
这篇文章介绍了作者在使用Adobe软件时遇到抓手工具无法切换的问题,并记录了排查与解决过程。最初通过“中/英键+空格”临时解除抓手锁定,但问题在多个软件中仍存在。作者逐步排除输入法、系统、账户、键盘等可能原因,最终发现是名为Fastzip的软件引起空格键失灵。卸载后问题解决。作者总结经验,建议遇到类似异常可先关闭可疑程序的输入监控与辅助功能权限,以快速定位问题。

macOS Tahoe 26 丑哭了
苹果推出了“液态玻璃” 升级视觉,号称 “惊艳新设计”。今晚看到 MacBook 的更新提醒,我没想太多就点了更新。当 macOS Tahoe 26 对我弹出液态的“你好”,我还有点新鲜感。但输入密码后,我后悔了,真的丑哭了。我不得不怀疑我的审美是不是跟不上时代了。
大大的圆角、忽大忽小的字体、粗鲁的滚动条、过度的透明、隐藏的返回按钮,还有让强迫症抓狂的文字和图标不中线对齐。确定发布的是正式版,不是测试版?
我要回滚系统,我要回滚系统。
![]()
![]()
![]()