Re: [問題] Obj-C++ and template

看板MacDev作者 (狗狗)時間10年前 (2013/09/24 00:39), 編輯推噓1(103)
留言4則, 2人參與, 最新討論串3/3 (看更多)

09/21 23:13,
其實template block...我還真想不到哪裡非用這種不可@@
09/21 23:13

09/21 23:13,
block其實就是lambda 就是個只需要用一次用過即丟的東西
09/21 23:13

09/23 03:33,
這個我倒是很樂觀clang會把它們整合在一起....
09/23 03:33

09/23 03:33,
不過我還是想不出有什麼原因會讓你不用templated func
09/23 03:33

09/23 03:33,
而非得搞個templated lambda不可 =P
09/23 03:33
在開發新的 programming 方式 最主要是讓部分程式碼以 block 包裝 然後在一個 function/method 內 讓這些 blocks 串在一起 (類似queue/chain) 然後從第一個 block 開始執行 並會在適當時機呼叫下一個 block 但也有可能不呼叫下一個 block 就立刻返回 目前已經開發差不多 (其實只有短短幾行 code) 但是遇到如果 function 有 return 值的話 每個中間經手的 block 都必須要回傳下一個 block 的回傳值 直到最後沒有 block 為止 通常最後一個 block 才是真正要執行的內容 而在執行最後一個 block 之前 可以先執行別的程式碼 我先把主架構(目前稱它為 Block-In-Block, BIB)的 code 貼上來: ===== Block-In-Block 主架構 ===== typedef void* (^BIBExecutionBlock)(); typedef BIBExecutionBlock (^BIBAdviceBlock)(BIBExecutionBlock executionBlock); BIBExecutionBlock BIBHandler(BIBAdviceBlock advice, ...); BIBExecutionBlock composeAdvices(BIBAdviceBlock headBlock, va_list tailBlocks); BIBExecutionBlock BIBHandler(BIBAdviceBlock advice, ...){ va_list advices_list; va_start(advices_list, advice); BIBExecutionBlock composedBlock = composeAdvices(advice, advices_list); va_end(advices_list); return composedBlock; } BIBExecutionBlock composeAdvices(BIBAdviceBlock headBlock, va_list tailBlocks){ if (headBlock == nil) { return nil; } return headBlock(composeAdvices(va_arg(tailBlocks, BIBAdviceBlock), tailBlocks)); } ========= 實作幾個 AdviceBlock ========= AOPAdviceBlock advice_1 = ^AOPExecutionBlock(AOPExecutionBlock furtherBlock){ return ^void*(){ void *retVal = NULL; printf("before advice_1\n"); // 若不呼叫 furtherBlock() 則不會執行下一個 block retVal = furtherBlock(); printf("after advice_1\n"); return retVal; }; }; AOPAdviceBlock advice_2 = ^AOPExecutionBlock(AOPExecutionBlock furtherBlock){ return ^void*(){ void *retVal = NULL; printf("before advice_2\n"); retVal = furtherBlock(); printf("after advice_2\n"); return retVal; }; }; =========== 實作兩個 method 使用 advice_1/advice_2 =========== @implementation BIBTest + (NSInteger) doubleTheNumber:(NSInteger)number{ return * (NSInteger*)BIBHandler(advice_1, advice_2, ^BIBExecutionBlock(BIBExecutionBlock furtherBlock){ return ^void*(){ NSLog(@"action"); NSInteger numberValue = number *2; void *retVal = &numberValue; return retVal; }; }, nil)(); } + (NSString*) logConsole:(NSString*)string{ return (__bridge NSString *)(BIBHandler(advice_1, advice_2, ^BIBExecutionBlock(BIBExecutionBlock furtherBlock){ return ^void*(){ NSLog(@"action for string: %@", string); NSString *newString = [NSString stringWithFormat:@"Hello, %@!", string]; return (__bridge void *)(newString); }; }, nil)()); } @end ========== 在 main() 呼叫這兩個 method ======== int main(int argc, char *argv[]) { NSLog(@"%@", [BIBTest logConsole: @"Tom"]); NSLog(@"===================="); NSLog(@"doubleTheNumber: %d", [BIBTest doubleTheNumber:50]); } =========== Console ============ > before advice_1 > before advice_2 > action for string: Tom > after advice_2 > after advice_1 > Hello, Tom! > ==================== > before advice_1 > before advice_2 > action > after advice_2 > after advice_1 > doubleTheNumber: 100 目前在處理 block-in-block 的回傳值問題 (應該還會牽扯到記憶體管理) 必須使用 void* 作為 BIBExecutionBlock 的回傳值 並在 function/method 內要重新 cast 才能回傳 希望可以自動判斷回傳型別 而不需要手動 cast 這個 progamming 的方式 可以讓各 block 決定是否呼叫下一個 block 並且可以竄改後面 block 回傳回來的值 (如果有必要的話) 因為目前 method 的實作 其實內部很多都是在做很多雜事 想把這些雜事轉為 block 可以讓 code 乾淨很多 (當然還是得搭配 macro) -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.198.184.235 ※ 編輯: leondemon 來自: 114.198.184.235 (09/24 01:01)

09/24 01:21, , 1F
你說的很像COR Pattern(Chains of Responbility)
09/24 01:21, 1F

09/24 01:21, , 2F
指的是這個嗎?所以你需要一個block產生器?
09/24 01:21, 2F

09/24 01:21, , 3F
噢搭macro的話....那可能能做的會比想像多很多...
09/24 01:21, 3F
不知道你說搭配的 marco 可以做的事有哪些 我已經有寫好 macro 可以比較像敘述的語法來寫 Code 會看起來比較簡潔 目前就是卡在 block 的回傳值要如何傳遞回去給 function 去 return 一直希望有解法至少可以看起來比較整潔一點... (如果可以用 Obj-C++ 解也OK) 這比較不像是責任鏈 責任鏈目的是要找到 responder 由它來負責處理 event 我的這個比較像是一個 hook 構造 假如 block 的排列順序為 A -> B -> C -> D -> T(目標 block) ... (後面還可以接其他 block) 則會執行 A -> B -> C -> D -> T -> D' -> C' -> B' -> A' 中間可以依判斷而終止往後傳而進行返回 例如 C 決定不呼叫下一個 block 則 A -> B -> C -> B' -> A' 搭配創造 block 的 method

09/24 10:31, , 4F
感覺像是js 的future/promise或是 FP的monad
09/24 10:31, 4F
沒特別研究別的 不過有空的話我再參考看看 Block-in-Block 只是一時興起的念頭 覺得這個 programming 方法有趣且應該有用 就開發來玩玩 ※ 編輯: leondemon 來自: 114.198.184.235 (09/25 00:55)
文章代碼(AID): #1IG6wuSP (MacDev)
文章代碼(AID): #1IG6wuSP (MacDev)