1. 程式人生 > >如何利用std::initializer_list讓你的初始化函式很騷

如何利用std::initializer_list讓你的初始化函式很騷

好久以前隨便瞎轉的時候看到一個 c++ 的 json 庫支援這樣的寫法,覺得非常酷,顛覆了c++的三觀。
(https://github.com/nlohmann/json)

// a way to express an _array_ of key/value pairs [["currency", "USD"], ["value", 42.99]]
json array_not_object = json::array({ {"currency", "USD"}, {"value", 42.99} });

於是就想這種騷操作怎麼實現的,現在我終於明白了:

#pragma once
#include "stdafx.h"
class TreeUnit; class TreeBuilder { public: TreeBuilder(std::initializer_list<TreeUnit> init_list) { } }; class TreeUnit { public: TreeUnit(const char* n) { wcout << "from string is called" << endl; } TreeUnit(Word::WordType word_type) { wcout << "from word_type is called"
<< endl; } };

這裡我們用 c 11 支援的新特性 std::initializer_list<TreeUnit> 允許了這樣一種初始化方式

TreeUnit treeUnit1, treeUnit2, treeUnit3;
TreeBuilder({ treeUnit1, treeUnit2, treeUnit3 });
TreeBuilder({ "xxx", Word::SomeType, treeUnit3 }); // SomeType 是 WordType 的一個列舉

這樣就達到了看起來“動態型別”的效果,實際上這個std::initializer_list<TreeUnit>

只支援 TreeUnit 的單引數建構函式的型別。

以下程式碼 Microsoft Visual C++ 2017 編譯通過

#pragma once
#include "stdafx.h"

class TreeUnit;

class TreeBuilder {
public:
    TreeBuilder(std::initializer_list<TreeUnit> init_list) {

    }
};

class TreeUnit {
public:
    TreeUnit(const char* n) {
        wcout << "from string is called" << endl;
    }
    TreeUnit(Word::WordType word_type) {
        wcout << "from word_type is called" << endl;
    }
};

...

void test_func_4() {
    TreeBuilder tb1({ "fuk", Word::identifier });
    TreeBuilder tb2({ Word::identifier, "fuk" });
}
from string is called
from word_type is called
from word_type is called
from string is called

相關推薦

如何利用std::initializer_list初始函式

好久以前隨便瞎轉的時候看到一個 c++ 的 json 庫支援這樣的寫法,覺得非常酷,顛覆了c++的三觀。 (https://github.com/nlohmann/json) // a way to express an _array_ of key/v

廖威雄: 思維導圖:利用__attribute__((section()))構建初始函式表與Linux核心init的實現

本文具體解說了利用__attribute__((section()))構建初始化函式表。以及Linux核心各級初始化的原理。 作者簡單介紹:     廖威雄,2016年本科畢業於暨南大學。眼下就職於珠海全志科技股份有限公司從事linu

利用__attribute__((section()))構建初始函式表【轉】

轉自: https://mp.weixin.qq.com/s?__biz=MzAwMDUwNDgxOA==&mid=2652663356&idx=1&sn=779762953029c0e0946c22ef2bb0b754&chksm=810f28a1b678a1b

利用gcc的__attribute__編譯屬性section子項構建初始函式

gcc的__attribute__編譯屬性有很多子項,用於改變作用物件的特性。這裡討論section子項的作用。 __attribute__的section子項使用方式為: __attribute__((section("section_name"))) 其作用是將作用的

RT-Thread 讀後感2——建立執行緒(定義執行緒的棧,定義執行緒函式,定義執行緒控制塊,執行緒初始函式

1. 定義執行緒的棧 多執行緒作業系統中,每個執行緒都是獨立的,互不干擾,所以要為每個執行緒分配獨立的棧空間,這個棧空間通常是一個預先定義好的全域性陣列, 也可以是動態分配的一段記憶體空間,但它們都存在於 RAM 中。定義兩個執行緒棧如下: // 定義執行緒棧 大小設定為512 rt_ui

pytorch系列 -- 9 pytorch nn.init 中實現的初始函式 uniform, normal, const, Xavier, He initialization

本文內容: 1. Xavier 初始化 2. nn.init 中各種初始化函式 3. He 初始化 torch.init https://pytorch.org/docs/stable/nn.html#torch-nn-init 1. 均勻分佈 torch.nn.init.u

tf.get_variable 中變數初始函式和Xavier初始

當使用 tf.get_variable(name, shape=None, initializer=None) 來定義變數時,可以利用變數初始化函式來實現對 initializer 的賦值。 在神經網路中,最常權重賦值方式是 正態隨機賦值 和 Xavier賦值。 1. 變數初始

python-初始函式

#本次學習:初始化函式 #-*- coding:utf-8 -*- class SeniorTestingEngineer: #初始化函式,在建立物件的時候就設定初始值 def __init__(self,name,work_year,salary): self.work_yea

1.面向過程程式設計 2.面向物件程式設計 3.類和物件 4.python 建立類和物件 如何使用物件 5.屬性的查詢順序 6.初始函式 7.繫結方法 與非繫結方法

1.面向過程程式設計 面向過程:一種程式設計思想在編寫程式碼時 要時刻想著過程這個兩個字過程指的是什麼? 解決問題的步驟 流程,即第一步幹什麼 第二步幹什麼,其目的是將一個複雜的問題,拆分為若干的小的問題,按照步驟一一解決,也可以說 將一個複雜的問題,流程化(為其制定一個固定的實現流程),從而變得簡單化例如

linux:核心如何定位並呼叫裝置驅動初始函式

寫過linux驅動程式的人都知道需要將驅動的初始化函式通過module_init註冊,然後在通過menuconfig配置的時候選擇隨核心一起編譯(非模組),系統在啟動的時候就能夠自動呼叫驅動初始化函數了。真是一件神奇的事情! #include <linu

初始函式的簡單寫法

struct seg { double l, r, h; int flag; seg() {} seg(double a,double b,double c,int d) : l(a), r(b), h(c), flag(d) {} bool oper

一篇文章掌握python函式引數的各種用法

  python的函式引數型別比較豐富,而且用法相對比較複雜,今天我們介紹幾種簡單常用的。 當然在學習Python的道路上肯定會困難,沒有好的學習資料,怎麼去學習呢? 學習Python中有不明白推薦加入交流群        

Java的初始函式

我們來考慮型別的裝載,連線和初始化 已經物件的生命週期。 可能出現在class檔案中的兩種編譯器產生的方法是: 例項初始化方法(名為<init>) 類與介面初始化方法(名為<clinit>)。 <clinit>方法依次執行如下語句:

---串列埠的配置初始函式------------------

#include <stdio.h> #include <stdlib.h> #include <termio.h> #include <unistd.h> #include <fcntl.h> #includ

Java在有繼承情況下初始函式的呼叫

廢話不多說,看下面的程式碼: public class Son extends Father{ int a = fun(); public int fun(){ System.out.println("son fun");

共享庫的初始和~初始函式分析

Win32下可以通過DllMain來初始化和~初始化動態庫,而Linux下則沒有與之完全對應的函式,但可以通過一些方法模擬它的部分功能。有人會說,很簡單,實現_init/_fini兩個函式就行了。好,我們來看看事實是不是這樣的。 很多資料上都說可以利用_init/_fini來實現,而我從來沒有測試成功

菜鳥stm32學習筆記(1)系統時鐘初始函式

系統初始化函式步驟: 1:復位並配置暫存器向量表。 2:置位CR第十六位,開啟外部振盪器。 3:檢測CR第十七位,判斷外部振盪器是否準備就緒。若就緒,硬體會置位十七位。 *2和3設定的均是時鐘控制暫存器。 4:設定時鐘配置暫存器CFGR的8-10位為100使得APB1的時鐘

python2,python3子類呼叫父類初始函式的方法和注意事項

python2、python3: python子類呼叫父類初始化函式有兩種方式,以下程式碼在python2和python3都能執行: class A(object): def __init__(self, x): self.x = x # 方法

初始函式(用純程式碼寫程式時)-給新手講解

是在GUI物件載入完成之後才能呼叫的方法  切記   2。可以用refreshList方法更新螢幕上控制元件;不過在控制元件過多的時候 用UItableView 更好 3。ini方法在是nib載入之前執行的  其模版是 -init {    self=[superself];//初始化父類成員    if(s

在驅動模組初始函式中實現裝置節點的自動建立(轉)

我們在剛開始寫Linux裝置驅動程式的時候,很多時候都是利用mknod命令手動建立裝置節點,實際上Linux核心為我們提供了一組函式,可以用來在模組載入的時候自動在/dev目錄下建立相應裝置節點,並在解除安裝模組時刪除該節點,當然前提條件是使用者空間移植了udev。  核心中定義了struct class結構