Merge branch 'master' of https://gitea.awin.one/awin/ObsidianMain.git
This commit is contained in:
2
.obsidian/app.json
vendored
2
.obsidian/app.json
vendored
@@ -14,5 +14,5 @@
|
||||
"newFileLocation": "current",
|
||||
"legacyEditor": false,
|
||||
"livePreview": false,
|
||||
"communityThemeSortOrder": "release"
|
||||
"communityThemeSortOrder": "download"
|
||||
}
|
||||
3
.obsidian/community-plugins.json
vendored
3
.obsidian/community-plugins.json
vendored
@@ -5,5 +5,6 @@
|
||||
"todoist-sync-plugin",
|
||||
"obsidian-columns",
|
||||
"obsidian-tasks-plugin",
|
||||
"obsidian-git"
|
||||
"obsidian-git",
|
||||
"oz-image-plugin"
|
||||
]
|
||||
4
.obsidian/note-composer.json
vendored
Normal file
4
.obsidian/note-composer.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"askBeforeMerging": true,
|
||||
"template": ""
|
||||
}
|
||||
13
.obsidian/plugins/oz-image-plugin/data.json
vendored
Normal file
13
.obsidian/plugins/oz-image-plugin/data.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"renderAll": true,
|
||||
"cm6RenderAll": true,
|
||||
"renderImages": true,
|
||||
"renderPDF": true,
|
||||
"renderIframe": false,
|
||||
"renderExcalidraw": false,
|
||||
"renderRichLink": false,
|
||||
"renderTransclusion": false,
|
||||
"previewOnHoverInternalLink": false,
|
||||
"refreshImagesAfterChange": false,
|
||||
"WYSIWYG": false
|
||||
}
|
||||
329
.obsidian/plugins/oz-image-plugin/main.js
vendored
Normal file
329
.obsidian/plugins/oz-image-plugin/main.js
vendored
Normal file
File diff suppressed because one or more lines are too long
10
.obsidian/plugins/oz-image-plugin/manifest.json
vendored
Normal file
10
.obsidian/plugins/oz-image-plugin/manifest.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"id": "oz-image-plugin",
|
||||
"name": "Ozan's Image in Editor Plugin",
|
||||
"version": "2.1.1",
|
||||
"minAppVersion": "0.13.14",
|
||||
"description": "View Images, Transclusions, iFrames and PDF Files within the Editor without a necessity to switch to Preview.",
|
||||
"author": "Ozan Tellioglu",
|
||||
"authorUrl": "https://ozan.pl/aboutme/",
|
||||
"isDesktopOnly": false
|
||||
}
|
||||
270
.obsidian/plugins/oz-image-plugin/styles.css
vendored
Normal file
270
.obsidian/plugins/oz-image-plugin/styles.css
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
.CodeMirror-linewidget img {
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.theme-dark img[alt$='#invert'],
|
||||
.theme-dark div.oz-image-widget > img[alt$='#invert'],
|
||||
.theme-dark div.oz-image-widget-cm6 > img[alt$='#invert'] {
|
||||
filter: invert(1) hue-rotate(180deg);
|
||||
}
|
||||
|
||||
.oz-transclusion-widget,
|
||||
.oz-transclusion-widget-cm6 {
|
||||
padding: 3px 3px 3px 19px;
|
||||
border: 0.7px solid var(--text-muted);
|
||||
max-height: 600px;
|
||||
overflow: auto;
|
||||
border-radius: 7px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.oz-coffee-div {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
/* Line Numbers In Editor CodeBlock Renders */
|
||||
pre[class*='language-'].line-numbers {
|
||||
position: relative;
|
||||
padding-left: 3.8em;
|
||||
counter-reset: linenumber;
|
||||
}
|
||||
pre[class*='language-'].line-numbers > code {
|
||||
position: relative;
|
||||
white-space: inherit;
|
||||
}
|
||||
.line-numbers .line-numbers-rows {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
top: 0;
|
||||
font-size: 100%;
|
||||
left: -3.8em;
|
||||
width: 3em; /* works for line-numbers below 1000 lines */
|
||||
letter-spacing: -1px;
|
||||
border-right: 1px solid #999;
|
||||
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
.line-numbers-rows > span {
|
||||
display: block;
|
||||
counter-increment: linenumber;
|
||||
}
|
||||
.line-numbers-rows > span:before {
|
||||
content: counter(linenumber);
|
||||
color: #999;
|
||||
display: block;
|
||||
padding-right: 0.8em;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.mermaid-error-information {
|
||||
color: red;
|
||||
font-size: 14px;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.oz-modal-center {
|
||||
text-align: center;
|
||||
margin: 20px 10px 20px 10px;
|
||||
}
|
||||
|
||||
.oz-modal-title {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.inline-mathjax-block {
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.oz-image-widget > img,
|
||||
.oz-image-widget-cm6 > img {
|
||||
-webkit-user-drag: none;
|
||||
user-select: none;
|
||||
-moz-user-select: none;
|
||||
-webkit-user-select: none;
|
||||
-ms-user-select: none;
|
||||
}
|
||||
|
||||
div.oz-transclusion-widget pre,
|
||||
div.oz-transclusion-widget-cm6 pre {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.oz-transclusion-widget > *,
|
||||
.oz-transclusion-widget-cm6 > * {
|
||||
user-select: text !important;
|
||||
}
|
||||
|
||||
/* Rich Link Cards */
|
||||
/* Credit: https://github.com/dhamaniasad/obsidian-rich-links */
|
||||
.oz-rich-link-card {
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 3px;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
text-decoration: none;
|
||||
background-color: var(--background-primary);
|
||||
}
|
||||
|
||||
.oz-rich-link-card-container {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.oz-rich-link-image-container {
|
||||
height: 100px;
|
||||
width: 35%;
|
||||
min-width: 120px;
|
||||
overflow: hidden;
|
||||
border-right: 1px solid var(--background-modifier-border);
|
||||
}
|
||||
|
||||
.oz-rich-link-image {
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
padding-bottom: 100px;
|
||||
background-color: var(--background-secondary);
|
||||
}
|
||||
|
||||
.oz-rich-link-card-text {
|
||||
padding: 4px;
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
.oz-rich-link-card-title {
|
||||
font-family: sans-serif;
|
||||
font-size: 16px;
|
||||
margin: 0 0 4px 0;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
color: var(--text-normal);
|
||||
}
|
||||
|
||||
.oz-rich-link-card-description {
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
color: var(--text-muted);
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.oz-rich-link-href {
|
||||
font-family: sans-serif;
|
||||
font-size: 14px;
|
||||
margin: 0;
|
||||
color: var(--text-faint);
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 1;
|
||||
-webkit-box-orient: vertical;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.image-in-editor-settings-main-header {
|
||||
text-align: center !important;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.image-in-editor-cm-header {
|
||||
margin-top: 0px;
|
||||
}
|
||||
|
||||
.image-in-editor-editor-header {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
/* Sizing for CM5 and CM6 */
|
||||
|
||||
div.oz-image-widget > img[alt$='#small'],
|
||||
div.oz-image-widget-cm6 > img[alt$='#small'] {
|
||||
max-width: 75% !important;
|
||||
min-width: 200pt !important;
|
||||
}
|
||||
|
||||
div.oz-image-widget > img[alt$='#x-small'],
|
||||
div.oz-image-widget-cm6 > img[alt$='#x-small'] {
|
||||
max-width: 50% !important;
|
||||
min-width: 100pt !important;
|
||||
}
|
||||
|
||||
div.oz-image-widget > img[alt$='#xx-small'],
|
||||
div.oz-image-widget-cm6 > img[alt$='#xx-small'] {
|
||||
max-width: 25% !important;
|
||||
min-width: 50pt !important;
|
||||
}
|
||||
|
||||
/* Style For CM6 */
|
||||
|
||||
div.oz-image-widget-cm6,
|
||||
div.oz-custom-html-widget-cm6,
|
||||
div.oz-pdf-widget-cm6 {
|
||||
padding-top: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
div.oz-image-widget-cm6 + br,
|
||||
div.oz-custom-html-widget-cm6 + br,
|
||||
div.oz-pdf-widget-cm6 + br {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.cm-line div.oz-transclusion-widget-cm6 {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
|
||||
.cm-line div.oz-transclusion-widget-cm6 * {
|
||||
margin-block-start: 0px !important;
|
||||
margin-block-end: 0px !important;
|
||||
}
|
||||
|
||||
/* Legacy Admonition */
|
||||
|
||||
.oz-admonition {
|
||||
margin: 1.5em 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
page-break-inside: avoid;
|
||||
border-left: 0.3rem solid rgb(var(--oz-admonition-color));
|
||||
border-radius: 0.1rem;
|
||||
box-shadow: 0 0.2rem 0.5rem rgb(44, 43, 43);
|
||||
}
|
||||
|
||||
.oz-admonition-title {
|
||||
position: relative;
|
||||
padding: 15px 5px 15px 15px;
|
||||
font-weight: 700;
|
||||
background-color: rgba(var(--oz-admonition-color), 0.1);
|
||||
}
|
||||
|
||||
.oz-admonition-title-content {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
margin-top: 0 !important;
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.oz-admonition-content-holder {
|
||||
position: relative;
|
||||
padding-top: 15px;
|
||||
padding-bottom: 15px;
|
||||
}
|
||||
|
||||
.oz-admonition-content {
|
||||
margin: 10px 15px;
|
||||
position: relative;
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.oz-admonition-title-markdown {
|
||||
text-transform: capitalize;
|
||||
display: block;
|
||||
}
|
||||
2
.obsidian/templates.json
vendored
2
.obsidian/templates.json
vendored
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"folder": "PARA/003 - Resources(資源)/99. templates",
|
||||
"folder": "02. PARA/03. Resources(資源)/99. templates",
|
||||
"dateFormat": "YYYY-MM-DD",
|
||||
"timeFormat": "HH:mm:ss"
|
||||
}
|
||||
52
.obsidian/workspace
vendored
52
.obsidian/workspace
vendored
@@ -7,8 +7,12 @@
|
||||
"id": "cfe19fa2de06a1e6",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "empty",
|
||||
"state": {}
|
||||
"type": "markdown",
|
||||
"state": {
|
||||
"file": "00. TOP/01. TODO.md",
|
||||
"mode": "preview",
|
||||
"source": true
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -36,7 +40,7 @@
|
||||
"state": {
|
||||
"type": "search",
|
||||
"state": {
|
||||
"query": "",
|
||||
"query": "精確",
|
||||
"matchingCase": false,
|
||||
"explainSearch": false,
|
||||
"collapseAll": false,
|
||||
@@ -65,6 +69,7 @@
|
||||
"state": {
|
||||
"type": "backlink",
|
||||
"state": {
|
||||
"file": "00. TOP/01. TODO.md",
|
||||
"collapseAll": false,
|
||||
"extraContext": false,
|
||||
"sortOrder": "alphabetical",
|
||||
@@ -75,6 +80,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "f94af359d1970a2d",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {
|
||||
"file": "00. TOP/01. TODO.md"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"currentTab": 1
|
||||
},
|
||||
{
|
||||
"id": "a0240ced26011060",
|
||||
"type": "tabs",
|
||||
"children": [
|
||||
{
|
||||
"id": "18b9707a37e1188a",
|
||||
"type": "leaf",
|
||||
@@ -85,22 +107,24 @@
|
||||
"useHierarchy": true
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "f94af359d1970a2d",
|
||||
"type": "leaf",
|
||||
"state": {
|
||||
"type": "outline",
|
||||
"state": {}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"direction": "horizontal",
|
||||
"width": 300,
|
||||
"collapsed": true
|
||||
"width": 300
|
||||
},
|
||||
"active": "cfe19fa2de06a1e6",
|
||||
"lastOpenFiles": []
|
||||
"lastOpenFiles": [
|
||||
"00. TOP/01. TODO.md",
|
||||
"02. PARA/03. Resources(資源)/Design Pattern.md",
|
||||
"02. PARA/03. Resources(資源)/讀書筆記/20220526 - 深入淺出設計模式.md",
|
||||
"02. PARA/03. Resources(資源)/讀書筆記/20220619 - 精確的力量.md",
|
||||
"02. PARA/03. Resources(資源)/讀書筆記/20210723 - 高手學習.md",
|
||||
"01. Daily/2022/年度目標.md",
|
||||
"02. PARA/03. Resources(資源)/Tool Setup/Windows Setup.md",
|
||||
"02. PARA/03. Resources(資源)/00. Informations/Datas.md",
|
||||
"02. PARA/03. Resources(資源)/00. Informations/Logitech.md",
|
||||
"02. PARA/03. Resources(資源)/00. Informations/核芯達.md"
|
||||
]
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
# ME
|
||||
- [x] 作筆記:C++17 - share_ptr ✅ 2022-06-06
|
||||
- [x] 作筆記:C++17 - R value reference與std::move ✅ 2022-06-09
|
||||
- [ ] 作筆記:C++17 - Lambda
|
||||
- [x] 作筆記:C++17 - Lambda ✅ 2022-06-15
|
||||
- [ ] 補充英格蘭與蘇格蘭的歷史
|
||||
- [ ] 把RxKotlin讀完
|
||||
- [ ] [Branchless C++](https://www.youtube.com/watch?v=g-WPhYREFjk) 🛫 2022-06-20 📅 2022-07-04
|
||||
- [ ] C++ 完美轉發? 🛫 2022-06-22
|
||||
- [潮.C++11 | Perfect Forwarding std::forward 完美轉發你的需求](https://tjsw.medium.com/%E6%BD%AE-c-11-perfect-forwarding-%E5%AE%8C%E7%BE%8E%E8%BD%89%E7%99%BC%E4%BD%A0%E7%9A%84%E9%9C%80%E6%B1%82-%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90-f991830bcd84)
|
||||
|
||||
# WORK
|
||||
## Logitech
|
||||
@@ -14,12 +17,29 @@
|
||||
- [x] 在測試項目的主欄位上顯示resolution, format, fps 🛫 2022-06-06 📅 2022-06-10 ✅ 2022-06-09
|
||||
- [x] 在測試項目的主欄位上顯示test time 🛫 2022-06-06 📅 2022-06-10 ✅ 2022-06-09
|
||||
- [x] test config 🛫 2022-06-06 📅 2022-06-10 ✅ 2022-06-09
|
||||
- [x] Remove log file, only keep err file. 🛫 2022-06-14 📅 2022-06-17 ✅ 2022-06-15
|
||||
- [x] 在 image 上加一個「另開視窗」的link 🛫 2022-06-14 📅 2022-06-17 ✅ 2022-06-15
|
||||
- TestAllFormatsVTF
|
||||
- [x] 在測試細項表格上顯示詳細說明 🛫 2022-06-06 📅 2022-06-10 ✅ 2022-06-07
|
||||
- [x] Show "VideoFormats: "MaxFpsMaxResolutionOnly" to outside, let user understand the test purpose. 🛫 2022-06-06 📅 2022-06-10 ✅ 2022-06-08
|
||||
- [x] List max fps of all resolution of all format on side bar of section 🛫 2022-06-06 📅 2022-06-10 ✅ 2022-06-08
|
||||
- [x] Show all items if user tests "all fps" 🛫 2022-06-14 📅 2022-06-17 ✅ 2022-06-24
|
||||
- [x] Pass的標準應該是「FrameRateIsNotZero」,而不是「有preview就好」 🛫 2022-06-14 📅 2022-06-17 ✅ 2022-06-15
|
||||
- TestGpsDiff
|
||||
- [ ] List all format 🛫 2022-06-06 📅 2022-06-10
|
||||
- [x] List all format 🛫 2022-06-06 📅 2022-06-10 ✅ 2022-06-10
|
||||
- MISC
|
||||
- [ ] 請在測試報告的最前面,加入目前測試平台的資訊、電腦名稱,Windows 版本 🛫 2022-06-24
|
||||
- 例如: Station2,Windows 10, Version XXXX Station6,Windows 11, Version XXXX。因為最近Project team 有要求要提出幾個主要平台的測試結果。 我們目前的報告需要能看出在哪一個平台測試。
|
||||
- 3A test(AWB, AE, AF)
|
||||
- [ ] Support parallel test 🛫 2022-06-14 📅 2022-06-24
|
||||
- AWB
|
||||
- [ ] Test "auto" ability 🛫 2022-06-14 📅 2022-06-24
|
||||
- AE
|
||||
- [ ] Test "auto" ability 🛫 2022-06-14 📅 2022-06-24
|
||||
- AF
|
||||
- [ ] Test "auto" ability 🛫 2022-06-14 📅 2022-06-24
|
||||
- Tiny
|
||||
- [ ] Add HDMI test 🛫 2022-06-17 📅 2022-06-24
|
||||
|
||||
# All TODOs
|
||||
```tasks
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
- [x] [奪橋遺恨](https://www.books.com.tw/products/0010039381) ✅ 2022-01-03
|
||||
- [x] [海上霸權](https://www.books.com.tw/products/0010910935?sloc=main)) ✅ 2022-01-26
|
||||
- [x] [被發明的昨日](https://www.books.com.tw/products/0010890348) 🛫 2022-01-26 📅 2022-06-01 ✅ 2022-06-01
|
||||
- [ ] [精確的力量](https://www.books.com.tw/products/0010839555) 🛫 2022-06-01 📅 2022-06-15
|
||||
- [x] [精確的力量](https://www.books.com.tw/products/0010839555) 🛫 2022-06-01 📅 2022-06-15 ✅ 2022-06-19
|
||||
- [ ] [普遍鼎立的世界](https://www.books.com.tw/products/0010900399) 🛫 2022-06-16 📅 2022-06-30
|
||||
- 讀6本專業書
|
||||
- [x] [C++17](https://www.books.com.tw/products/0010844594) (2021/12/15-2022/06/01) 🛫 2021-12-15 📅 2022-06-01 ✅ 2022-06-01
|
||||
|
||||
223
02. PARA/03. Resources(資源)/C++17/lambda.md
Normal file
223
02. PARA/03. Resources(資源)/C++17/lambda.md
Normal file
@@ -0,0 +1,223 @@
|
||||
---
|
||||
tags:
|
||||
aliases:
|
||||
date: 2022-06-12
|
||||
time: 18:21:42
|
||||
description:
|
||||
---
|
||||
|
||||
一個簡單的 Lamdba 運算式:
|
||||
```cpp
|
||||
[] (int x, int y) -> bool {
|
||||
return x < y;
|
||||
}
|
||||
```
|
||||
|
||||
- 以中括號開頭,中括號被稱為*lamdba 導入器(lamdba introducer)*
|
||||
- 小括號裡面是*lamdba 參數列表(lambda parameter list)*
|
||||
- 如果沒有參數,小括號可以省略,`[] () {...}` 可以簡寫成 `[] {...}`
|
||||
- 箭號(`->`)後面是回傳的型別,如果沒寫就由 `return` 自動推斷
|
||||
|
||||
將 Lamdba 運算式指定給變數:
|
||||
```cpp
|
||||
auto comapre = [] (int x, int y) -> bool {
|
||||
return x < y;
|
||||
};
|
||||
```
|
||||
|
||||
## Lamdba的擷取子句
|
||||
以中括號開頭的 *lamdba 導入器* 可以將外部的變數傳給 Lamdba 運算式,正式名稱是「擷取子句(capture clause)」。
|
||||
`[=]` 表示它們會以值擷取(captured by value)。Scope內的變數可以在 lamdba 內使用,但是不可以改變。
|
||||
`[&]` 表示它們會以參考擷取(captured by reference)。Scope內的變數可以在 lamdba 內使用,可以改變。
|
||||
|
||||
## 以值擷取(captured by value)
|
||||
假設有一段程式如下:
|
||||
```cpp
|
||||
void testLambda() {
|
||||
float notUsed = 1.0f;
|
||||
std::vector<int32_t> numlist{10, 20, 30, 50, 60};
|
||||
auto findInRange = [=](int32_t start, int32_t end) {
|
||||
for (auto num : numlist) {
|
||||
if (num >= start && num <= end) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::cout << "Result: " << findInRange(25, 35) << "\n";
|
||||
}
|
||||
```
|
||||
|
||||
用`[=]`可以用來擷取 lamdba scope 範圍所及的變數,沒有在 Lamdba 運算式裡面被用到的變數就不會被擷取,例如 `float notUsed = 1.0f;`。
|
||||
另一個重點是:**被擷取的變數是不可以更改的**。例如,不能在 lambda 裡面這樣寫:
|
||||
```cpp
|
||||
auto findInRange = [=](int32_t start, int32_t end) {
|
||||
numlist.push_back(5); // ERROR!
|
||||
|
||||
for (auto num : numlist) {
|
||||
if (num >= start && num <= end) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
```
|
||||
|
||||
如果一定要在 lambda 內改變擷取的變數,那必須指名 lambda 為 `mutable`:
|
||||
```cpp
|
||||
auto findInRange = [=](int32_t start, int32_t end) mutable { // <-- assign mutable
|
||||
numlist.push_back(5);
|
||||
|
||||
for (auto num : numlist) {
|
||||
if (num >= start && num <= end) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
```
|
||||
|
||||
根據書上解釋 ,可以裡解為 compiler 會將 lamdba 編為一個 class,像是:
|
||||
```cpp
|
||||
class __Lambda8C1A5 {
|
||||
public:
|
||||
__Lambda8C1A5(const std::vector<int32_t>& arg1) : numlist(arg1) {}
|
||||
auto operator()(int32_t start, int32_t end) const { // const!
|
||||
for (auto num : numlist) {
|
||||
if (num >= start && num <= end) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<int32_t> numlist;
|
||||
};
|
||||
```
|
||||
|
||||
這也解釋了 lamdba 的擷取範圍與原理。而 `mutable` 則是讓 `operator()` 不為 `const`,如下:
|
||||
```cpp
|
||||
auto findInRange = [=](int32_t start, int32_t end) mutable { // <-- assign mutable
|
||||
numlist.push_back(5);
|
||||
|
||||
for (auto num : numlist) {
|
||||
if (num >= start && num <= end) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
...
|
||||
|
||||
class __Lambda8C1A5 {
|
||||
public:
|
||||
__Lambda8C1A5(const std::vector<int32_t>& arg1) : numlist(arg1) {}
|
||||
auto operator()(int32_t start, int32_t end) { // No const here
|
||||
for (auto num : numlist) {
|
||||
if (num >= start && num <= end) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<int32_t> numlist;
|
||||
};
|
||||
```
|
||||
|
||||
## 以值擷取特定的變數
|
||||
若只需要擷取特定的變數,那就直接在 lamdba 導入器(就是`[]`)寫入變數名稱,例如:
|
||||
```cpp
|
||||
int var1 = 10;
|
||||
int var2 = 20;
|
||||
int var3 = 30;
|
||||
|
||||
auto afunc = [var1, var2] () {
|
||||
...
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
## 以參考擷取(captured by reference)
|
||||
`[&]` 會擷取 scope 內的所有外部變數,而且可以修改:
|
||||
```cpp
|
||||
void testLambda() {
|
||||
float notUsed = 1.0f;
|
||||
std::vector<int32_t> numlist{ 10, 20, 30, 50, 60 };
|
||||
auto findInRange = [&](int32_t start, int32_t end) { // Use & here
|
||||
numlist.push_back(100); // OK
|
||||
|
||||
for (auto num : numlist) {
|
||||
if (num >= start && num <= end) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
std::cout << "Result: " << findInRange(25, 35) << "\n";
|
||||
std::cout << "numlist: ";
|
||||
for (auto n : numlist) {
|
||||
std::cout << n << " ";
|
||||
}
|
||||
std::cout << "\n"; // Output numlist: 10 20 30 50 60 100
|
||||
}
|
||||
```
|
||||
|
||||
## 以參考擷取特定的變數
|
||||
但是直接參考全部的外部變數不是好的作法,這讓你有機會做出一些意外的修改,所以請擷取有需要的變數就好:
|
||||
```cpp
|
||||
void testLambda() {
|
||||
float notUsed = 1.0f;
|
||||
std::vector<int32_t> numlist{ 10, 20, 30, 50, 60 };
|
||||
|
||||
auto findInRange = [&numlist](int32_t start, int32_t end) {
|
||||
numlist.push_back(100); // OK
|
||||
|
||||
for (auto num : numlist) {
|
||||
if (num >= start && num <= end) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
如果有多個變數需要擷取,那就用 `,` 分開:
|
||||
```cpp
|
||||
auto findInRange = [&numlist, &var1, &var2](int32_t start, int32_t end) {
|
||||
...
|
||||
};
|
||||
```
|
||||
|
||||
## 混合擷取
|
||||
以值擷取跟參考擷取也可以寫在一起:
|
||||
```cpp
|
||||
auto findInRange = [=, &numlist](int32_t start, int32_t end) {
|
||||
...
|
||||
};
|
||||
```
|
||||
上面的例子中,`numlist` 會是參考擷取,其他的外部變數則是以值擷取。
|
||||
|
||||
或是:
|
||||
```cpp
|
||||
auto findInRange = [&, numlist](int32_t start, int32_t end) {
|
||||
...
|
||||
};
|
||||
```
|
||||
上面的例子中,`numlist` 會以值擷取,其他的外部變數則是參考擷取。
|
||||
|
||||
但是,如果已經使用了 `=` ,就不可以再以值擷取其他變數,像是 `[=, numlist]` 就是不合法的。
|
||||
反之,如果已經使用了 `&`,就不可以再參考擷取其他變數,像是 `[&, &var1]` 就是不合法的。
|
||||
|
||||
|
||||
## 存取 class
|
||||
Lamdba 寫在 class 裡面的時候,不論 [[lambda#以值擷取(captured by value)|以值擷取]]或是 [[lambda#以參考擷取(captured by reference)|以參考擷取]]都沒辦法傳遞成員變數(member variable),只能傳遞 `this`,透過 `this` 來存取成員變數。例:
|
||||
```cpp
|
||||
class BigBuffer {
|
||||
public:
|
||||
void modify(int x, int y, ...) {
|
||||
auto modifyBuffer = [this] () { // Use this
|
||||
if (buffer) { // equal to this->buffer
|
||||
// do something with buffer
|
||||
}
|
||||
};
|
||||
...
|
||||
}
|
||||
|
||||
private:
|
||||
uint32_t bufferSize = 0;
|
||||
std::unique_ptr<uint8_t[]> buffer = nullptr;
|
||||
};
|
||||
```
|
||||
@@ -10,7 +10,7 @@ description:
|
||||
策略模式可以提供不一樣的演算法,但是又不用更改程式。
|
||||
以常見的鴨子為例,有一個基礎類別Duck,如何衍生出會飛得鴨子跟不會飛的鴨子?抑或是會叫的跟不會叫的?
|
||||
第一部是將會變動的部份分離出來,讓鴨子類別不需要去在乎飛跟叫的問題。
|
||||
再來是把飛跟叫的部份包裝成另一個class,並以之為基礎類別來實做出「實際的類別」。
|
||||
再來是把飛跟叫的部份包裝成另一個class,並以之為基礎類別來實做出「實際的類別」。 ^e59e9f
|
||||
|
||||
以一般C++的override方法,會用的方式大致是這樣:
|
||||
|
||||
@@ -131,3 +131,110 @@ class duckWood : public duck {
|
||||
![[Pasted image 20220526183019.png]]
|
||||
|
||||
這樣做的另一個好處是fly的初始化是動態的,只要再多一個`set()` function就可以動態的切換實作,也就是說你可以從設定檔來決定你的鴨子要長什麼樣子。
|
||||
|
||||
|
||||
## 觀察者模式(Observer Pattern )
|
||||
有一個會產生變動的主角(subject),與一堆需要觀察變動的觀察者(Observer)。觀察者向主角註冊,當主角發生變化的時候,發後通知給觀察者。
|
||||
![[20220614154819_Observer_Pattern.png]]
|
||||
|
||||
Subject方面,attach() 就是註冊觀察者,也可以叫做 register()、add() 之類。
|
||||
detach() 用來移除用戶,也可以叫做 unregister()、remove() 之類。
|
||||
notify()則是當發生變化時,用來通知所有觀察者的實作。
|
||||
|
||||
觀察者方面必須實作 update() 才能收到通知。
|
||||
|
||||
## 裝飾者模式(Decorator Pattern)
|
||||
「裝飾者」通常與「被裝飾者」有同樣的界面,「裝飾者」會取代「被裝飾者」的界面,進而改變「被裝飾者」的行為。
|
||||
裝飾者模式讓物件可以動態的改變行為,進為符合不同的需求。
|
||||
以書上的例子來說,我們多種飲料,每種飲料都可以加上不同的配料。例如,有奶茶、綠茶、紅茶3種飲料,另外有珍珠、紅豆、綠豆、仙草4種配料,我們要如何設計出適合的類別來讓每種飲料都可以隨寄的搭配配料呢?
|
||||
|
||||
假設這樣寫:
|
||||
- !!!col
|
||||
- 1
|
||||
### Ingredient class
|
||||
```cpp
|
||||
class IngredientBubble { ... };
|
||||
class IngredientRedbean { ... };
|
||||
class IngredientGreenbean { ... };
|
||||
class IngredientFairyGrass { ... };
|
||||
```
|
||||
|
||||
- 1
|
||||
### Beverage class
|
||||
```cpp
|
||||
class Beverage {
|
||||
int32_t cost() { return cost; }
|
||||
int32_t cost;
|
||||
}
|
||||
|
||||
class BeverageMilkTea : public Beverage { ... };
|
||||
class BeverageGreenTea : public Beverage { ... };
|
||||
class BeverageBlackTea : public Beverage {
|
||||
IngredientBubble* bubble;
|
||||
IngredientRedbean* redbean;
|
||||
IngredientGreenbean* greenbean;
|
||||
IngredientFairyGrass* fairyGrass;
|
||||
}
|
||||
```
|
||||
|
||||
每個飲料的class裡面都將每個配料定義為一個 member,如果客人有加配料的話,我們就將配料實例化,假設奶茶加了珍珠:
|
||||
```cpp
|
||||
class BeverageBlackTea {
|
||||
void addBubble() {
|
||||
if (!bubble) bubble = new IngredientBubble();
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
要算價格的時候:
|
||||
```cpp
|
||||
class BeverageBlackTea {
|
||||
int32_t cost() {
|
||||
if (bubble) cost += 10; // 珍珠要加10元
|
||||
if (redbean) cost += 5; // 紅豆要加10元
|
||||
if (greenbean) cost += 7; // 綠豆要加10元
|
||||
if (fairyGrass) cost += 9; // 珍珠要加10元
|
||||
return cost;
|
||||
}
|
||||
int32_t cost = 30; // 奶茶本身10元
|
||||
};
|
||||
```
|
||||
|
||||
這樣的問題是,每當有一種新配料出現,我們就要在奶茶類別裡修改至少2個 function:`addXXX()` 與 `cost()`,目前我們有3種飲料,所以要修改6個 function,更何況,如果客人要加2份珍珠怎麼辦?這明顯不利程式的維護,必須有一種方法讓程式的修改最小,讓寫好的程式不用被修改才行。
|
||||
|
||||
讓裝飾者模式來改善這個問題。首先讓配料跟飲料有同樣的界面,但是修改一下配料的 constructor,當然也要實作 `cost()`,畢竟每個配料的價格不同:
|
||||
```cpp
|
||||
class IngredientBubble : public Beverage {
|
||||
IngredientBubble(Beverage* beverage) {
|
||||
this->beverage = beverage;
|
||||
}
|
||||
|
||||
int32_t cost() {
|
||||
return 10 + this->beverage->cost(); // 珍珠要加10元,在加上原本飲料的價錢
|
||||
}
|
||||
|
||||
Beverage* beverage;
|
||||
};
|
||||
```
|
||||
|
||||
珍珠這個 class 的 constructor 的參數是任何一個 Beverage,現在飲料被包在珍珠裡面,由珍珠來決定飲料最後的價格是多少。現在我們可以動態的決定飲料的組成,假設點一杯紅茶,加一些配料:
|
||||
```cpp
|
||||
int main() {
|
||||
...
|
||||
|
||||
// 為了讓程式看起來簡單,這裡就先不考慮memory leak的問題...>_<
|
||||
BeverageBlackTea* berverge = new BeverageBlackTea(); // 點一杯紅茶
|
||||
IngredientBubble* berverge = new IngredientBubble(berverge); // 加珍珠
|
||||
IngredientRedbean* berverge = new IngredientRedbean(berverge); // 加紅豆
|
||||
IngredientFairyGrass* berverge = new IngredientFairyGrass(berverge); // 加仙草
|
||||
|
||||
...
|
||||
|
||||
return berverge->cost(); // 算價錢
|
||||
}
|
||||
```
|
||||
|
||||
可以看到第一個變數是飲料,然後被包珍珠裡面,變成珍珠紅茶,再被包到紅豆裡面,變成紅豆珍珠紅茶,再被包到仙草裡面,變成仙草紅豆珍珠紅茶,到這樣的好處是:
|
||||
1. 有新的配料就寫新配料的 class
|
||||
2. 因為可以動態的組合,原本寫好的飲料 class 就不用在去動它了,愈少修改,愈少 bug
|
||||
3. 我們可以動態的組合配料,要加2份以上也沒有問題
|
||||
|
||||
@@ -9,7 +9,7 @@ Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManage
|
||||
```
|
||||
2. 用安裝常用的工具
|
||||
```
|
||||
choco install 7zip adobereader vscode hxd sublimetext4 microsoft-windows-terminal androidstudio intellijidea-community git winmerge freefilesync freedownloadmanager gsudo firacode cascadiacode sourcecodepro --yes
|
||||
choco install 7zip adobereader vscode hxd sublimetext4 microsoft-windows-terminal androidstudio intellijidea-community git winmerge freefilesync freedownloadmanager gsudo firacode cascadiacode sourcecodepro delta --yes
|
||||
```
|
||||
|
||||
列表:
|
||||
@@ -29,6 +29,7 @@ choco install 7zip adobereader vscode hxd sublimetext4 microsoft-windows-termina
|
||||
- [firacode](https://community.chocolatey.org/packages/FiraCode)
|
||||
- [cascadiacode](https://community.chocolatey.org/packages/cascadiacode)
|
||||
- [sourcecodepro](https://community.chocolatey.org/packages/SourceCodePro)
|
||||
- [delta](https://community.chocolatey.org/packages/delta)
|
||||
|
||||
移除:
|
||||
- [TeraCopy](https://chocolatey.org/packages/TeraCopy)
|
||||
|
||||
@@ -107,8 +107,11 @@ unset THEME
|
||||
"commandline": "%PROGRAMFILES%/git/usr/bin/bash.exe -i -l",
|
||||
"icon": "%PROGRAMFILES%/Git/mingw64/share/git/git-for-windows.ico",
|
||||
"startingDirectory" : "D:\\GoogleDrive\\codes",
|
||||
"fontFace" : "Fira Code",
|
||||
"fontSize" : 11,
|
||||
"font":
|
||||
{
|
||||
"face": "CaskaydiaCove NF",
|
||||
"size": 12
|
||||
},
|
||||
"historySize" : 9000,
|
||||
},
|
||||
]
|
||||
@@ -155,5 +158,24 @@ unset THEME
|
||||
}
|
||||
```
|
||||
|
||||
## oh-my-posh on bash
|
||||
以下步驟都是在 [Windows Terminal](https://apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701) 中的 Git bash[^1] 執行。
|
||||
1. 先下載一個你喜歡的theme: [https://ohmyposh.dev/docs/themes](https://ohmyposh.dev/docs/themes)
|
||||
2. 下載並安裝字型:[Caskaydia Cove Nerd Font](https://github.com/ryanoasis/nerd-fonts/releases/download/v2.1.0/CascadiaCode.zip?WT.mc_id=-blog-scottha)
|
||||
3. Install OhMyPosh: `winget install JanDeDobbeleer.OhMyPosh`
|
||||
4. 建立並修改 `~/.profile`,然後加入
|
||||
`eval "$(oh-my-posh --init --shell bash --config ~/OneDrive/appConfigs/ohmyposh/themes/montys.omp.json)"`
|
||||
注意最後的 `montys.omp.json` 就是第一步下載的theme,這邊要改成你自己的路徑。
|
||||
5. 修改 Windows Terminal 的 setting.json,將字型改為 `CaskaydiaCove NF`
|
||||
![[20220614221618_oh-my-posh_setting.png|600]]
|
||||
6. 成果
|
||||
![[20220614220342_oh-my-posh_result.png|600]]
|
||||
|
||||
[^1]: 在 [Windows Terminal](https://apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701) 中設定 Git bash 可以參考:[Windows Terminal's 設定 Git Bash 和 SSH @ 傑克! 真是太神奇了! :: 痞客邦 ::](https://magicjackting.pixnet.net/blog/post/225162505-windows-terminal's-%E8%A8%AD%E5%AE%9A-git-bash-%E5%92%8C-ssh)
|
||||
|
||||
## Reference
|
||||
- [Windows Terminal 美化 for WSL 2 Ubuntu (zsh + zim + powerlevel10k)](http://www.kenming.idv.tw/windows-terminal-%e7%be%8e%e5%8c%96-for-wsl-2-ubuntu-zsh-zim-powerlevel10k/)
|
||||
- [Oh My Posh](https://ohmyposh.dev/)
|
||||
- [How to make the ultimate Terminal Prompt on Windows 11 - This video is LONG and WORDY and DETAILED - YouTube](https://www.youtube.com/watch?v=VT2L1SXFq9U)
|
||||
- [My Ultimate PowerShell prompt with Oh My Posh and the Windows Terminal - Scott Hanselman's Blog](https://www.hanselman.com/blog/my-ultimate-powershell-prompt-with-oh-my-posh-and-the-windows-terminal)
|
||||
- [Windows-Terminal配置OhMyPosh来美化GitBash_偕臧x的博客-CSDN博客](https://blog.csdn.net/qq_33154343/article/details/120661945)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
git submodule add <repository> [<local_path>]
|
||||
```
|
||||
新增之後,用 git status 會發現多了兩個東西需要 commit:
|
||||
![[Pasted image 20220608152709.png]]
|
||||
![[20220608152709_git_submodule.png|450]]
|
||||
|
||||
第一個檔案 .gitmodules,裡面紀錄 submodule 的對應關係,內容大概像這樣:
|
||||
```
|
||||
|
||||
16
02. PARA/03. Resources(資源)/讀書筆記/20220619 - 精確的力量.md
Normal file
16
02. PARA/03. Resources(資源)/讀書筆記/20220619 - 精確的力量.md
Normal file
@@ -0,0 +1,16 @@
|
||||
書名:
|
||||
日期:2022-06-19(週日)
|
||||
Link:[精確的力量](https://www.books.com.tw/products/0010839555)
|
||||
|
||||
# 筆記
|
||||
|
||||
|
||||
# 心得
|
||||
作者從精度最不要求的部份開始說,從大英帝國對於帆船滑輪的需求開始說起,然後槍枝、汽車、鏡片,最後不可避免的講到了IC的製程。然而我覺得最有意思的是蒸汽機與哈伯望遠鏡。
|
||||
雖然一直知道瓦特發明了蒸汽機進而引發工業革命,也進一步改變了世界,但讓蒸氣機能夠穩定運作且能夠實用化的關鍵原因是威爾金森的活塞工藝,威爾金森在製造加農砲時所發明的加工挖孔技術適時的幫上了瓦特的忙,才讓蒸汽機的效率能夠實用化。
|
||||
|
||||
再來是哈伯望遠鏡的初期失敗是源自於鏡片製造商的失誤,而鏡片製造商的失敗又來自於多個失誤的累積,這些失誤都不是一下子造成的,而是一個一個慢慢累積的,這讓我又再次感覺到生活上培養習慣的重要性,壞習慣的積累往往也是讓某個失誤在某個時間爆發的原因,只是累積的時間太長,讓我們又無法一次看到事情發生的根本,而又讓相同的錯誤一再發生。
|
||||
|
||||
再來,從書中所寫的各個精密製造的發展過程,可以看到近日我們習以為常的產品、標準,其實都是由很多優秀、天才的人貢獻、累積而來的,沒有什麼橫空出世的天才,憑一人之力改變世界這種事。每個人都是站在前人的肩膀上,一步一步的改進而來,扎實的研究與實作才是最重要的。
|
||||
|
||||
# TODO
|
||||
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
BIN
attachments/20220614154819_Observer_Pattern.png
Normal file
BIN
attachments/20220614154819_Observer_Pattern.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
BIN
attachments/20220614220342_oh-my-posh_result.png
Normal file
BIN
attachments/20220614220342_oh-my-posh_result.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
attachments/20220614221618_oh-my-posh_setting.png
Normal file
BIN
attachments/20220614221618_oh-my-posh_setting.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 82 KiB |
Reference in New Issue
Block a user