{"id":23772979,"url":"https://github.com/huanhuanonly/cpp-kwargs","last_synced_at":"2025-04-09T15:06:22.897Z","repository":{"id":270190668,"uuid":"909589513","full_name":"huanhuanonly/cpp-kwargs","owner":"huanhuanonly","description":"Implement Python's kwargs-style parameter passing in C++. 在 C++ 中实现 Python 的 Kwargs 风格传参。","archived":false,"fork":false,"pushed_at":"2025-04-09T04:00:49.000Z","size":219,"stargazers_count":87,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-09T15:06:16.193Z","etag":null,"topics":["args","c-plus-plus","cplusplus","cpp","cpp-any","cpp-kwargs","dict-python","header-only","initializer-list","kwargs","library","python","type-converter"],"latest_commit_sha":null,"homepage":"https://github.com/huanhuanonly","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/huanhuanonly.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-12-29T07:04:55.000Z","updated_at":"2025-04-09T04:00:53.000Z","dependencies_parsed_at":"2024-12-29T08:22:35.012Z","dependency_job_id":"1ded7b1a-ae85-4d1e-a162-6094bb33a549","html_url":"https://github.com/huanhuanonly/cpp-kwargs","commit_stats":null,"previous_names":["huanhuanonly/cpp-kwargs"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huanhuanonly%2Fcpp-kwargs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huanhuanonly%2Fcpp-kwargs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huanhuanonly%2Fcpp-kwargs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/huanhuanonly%2Fcpp-kwargs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/huanhuanonly","download_url":"https://codeload.github.com/huanhuanonly/cpp-kwargs/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248055284,"owners_count":21040157,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["args","c-plus-plus","cplusplus","cpp","cpp-any","cpp-kwargs","dict-python","header-only","initializer-list","kwargs","library","python","type-converter"],"created_at":"2025-01-01T05:21:39.662Z","updated_at":"2025-04-09T15:06:22.876Z","avatar_url":"https://github.com/huanhuanonly.png","language":"C++","readme":"\u003cdiv align=\"center\"\u003e\n\n# cpp-kwargs\n\n[![STD-CPP](https://img.shields.io/badge/STD%20C%2B%2B-20-darkorange?style=for-the-badge\u0026logo=C%2B%2B\u0026logoColor=white\u0026logoSize=auto\u0026labelColor=darkcyan)](https://en.cppreference.com/w/cpp/20)\n[![ENGLISH](https://img.shields.io/badge/English-goto-lavender?style=for-the-badge\u0026logo=googletranslate\u0026logoColor=white\u0026logoSize=auto\u0026labelColor=lightskyblue)](./README_English.md)\n[![VIEW-CODE](https://img.shields.io/badge/VIEW-CODE-greed?style=for-the-badge\u0026logo=github\u0026logoColor=white\u0026logoSize=auto\u0026labelColor=blue)](https://github.com/huanhuanonly/cpp-kwargs/blob/main/CppKwargs.h)\n[![EXAMPLES-MORE](https://img.shields.io/badge/EXAMPLES-MORE-gold?style=for-the-badge\u0026logo=openbugbounty\u0026logoColor=white\u0026logoSize=auto\u0026labelColor=orange)](https://github.com/huanhuanonly/cpp-kwargs/blob/main/test.cpp)\n[![DOCS](https://img.shields.io/badge/Detailed-Documentation-darkcyan?style=for-the-badge\u0026logo=googledocs\u0026logoColor=white\u0026labelColor=cornflowerblue\n)](https://github.com/huanhuanonly/cpp-kwargs/tree/main/docs)\n\n\n**_cpp-kwargs 是一个能在 C++ 中实现类似于 Python `**kwargs` 传参的库。_**\n\n**_它通过 C++ 强大的模板编程封装了一个 [`Kwargs`](./docs/Kwargs.md) 类以此来实现了该功能。_**\n\n\u003cdetails\u003e\n    \u003csummary\u003e\n            Python 中的 \u003ccode\u003e**kwargs\u003c/code\u003e\n    \u003c/summary\u003e\n\n_在 Python 中， `**Kwargs` 用于函数定义时接受任意数量的关键字参数。它将所有通过 `Key=Value` 形式传递的参数封装成一个字典，在函数内部可以通过 `kwargs` 访问这些参数，`**kwargs` 使得函数能够灵活地接受不定数量的关键字参数，提升了代码的可扩展性。[官方文档](https://docs.python.org/3/tutorial/controlflow.html#keyword-arguments)。_\n\n\u003c/details\u003e\n\n\u003c/div\u003e\n\n## 文档\n\n- [Kwargs](./docs/Kwargs.md) | [Kwargs::DataItem](./docs/Kwargs_DataItem.md)\n- [KwargsKey](./docs/KwargsKey.md)\n- [KwargsValue](./docs/KwargsValue.md)\n- [operator\"\"_opt](./docs/operator%20_opt.md)\n\n## [功能 \u0026 示例](https://github.com/huanhuanonly/cpp-kwargs/blob/main/test.cpp)\n\n* _Python (**kwargs)_ 和 _cpp-kwargs_ 都支持的：\n\n  - [x] 支持 **按任意顺序排列的** 键；\n  - [x] 支持 **缺少的** 或 **多余的** 键；\n  - [x] 支持 **限定键名**；\n  - [x] 支持 **任意类型的** 值；\n  - [x] 保留 **原始值的类型信息**；\n\n* _cpp-kwargs_ 额外支持的：\n\n  - [x] 自动的 [类型转换](#支持的内置类型自动转换)（传入类型和传出的类型不一致时）；\n  - [x] 较小的开销，`Kwargs` 的内部会尽可能地使用 `constexpr`，将在 **编译期得到结果** （如果满足条件的话）；\n  - [x] 键名不区别大小写（_可选的_）；\n\n\u003e [!TIP]\n\u003e 推荐使用 C++ $20$，在 C++ $20$ 中，`STL` 更多的被声明为 `constexpr`，代码的 _编写_ 和 _测试_ 皆在 C++ $20$ 中完成。\n\n* 仅 _Python (**kwargs)_ 支持的：\n\n  - [ ] 动态的返回值类型；\n\n\u003e [!TIP]\n\u003e C++ 的返回值类型必须在编译时确定。\n\n### 应用在函数中\n\n\u003cdetails open\u003e\n\u003csummary\u003e函数原型\u003c/summary\u003e\n\n- In _**Python**_:\n  ```py\n  # 任意的键名\n  def func(**kwargs): ...\n  \n  # 限定键名（带默认值）\n  def func(*, name='empty_name', old=0): ...\n  ```\n\n- In _**C++**_:\n  ```cpp\n  // 任意的键名\n  auto func(Kwargs\u003c\u003e kwargs = {})\n  {...}\n\n  // 限定键名（无需带默认值）\n  auto func(Kwargs\u003c\"name\"_opt, \"old\"_opt\u003e kwargs = {})\n  {...}\n  ```\n\n\u003c/details\u003e\n\n\u003cdetails open\u003e\n\u003csummary\u003e外部调用\u003c/summary\u003e\n\n- In _**Python**_:\n  ```py\n  # 正常\n  func(name='huanhuanonly', old=18)\n\n  # 非预期的类型\n  func(name='huanhuanonly', old='18')\n\n  # 相反的顺序\n  func(old=18, name='huanhuanonly')\n\n  # 空的参数\n  func()\n  ```\n\n- In _**C++**_:\n  ```cpp\n  // 正常\n  func({ {\"name\", \"huanhuanonly\"}, {\"old\", 18} });\n\n  // 非预期的类型\n  func({ {\"name\", \"huanhuanonly\"}, {\"old\", \"18\"} });\n\n  // 相反的顺序\n  func({ {\"old\", 18}, {\"name\", \"huanhuanonly\"} });\n\n  // 空的参数\n  func()\n  ```\n\n\u003c/details\u003e\n\n\u003cdetails open\u003e\n\u003csummary\u003e内部获取值\u003c/summary\u003e\n\n- In _**Python**_:\n  ```py\n  str(kwargs['name']) if 'name' in kwargs else 'empty_name'\n\n  int(kwargs['old']) if 'old' in kwargs else 0\n  ```\n\n- In _**C++**_:\n  ```cpp\n  kwargs[\"name\"].valueOr\u003cstd::string\u003e(\"empty_name\")\n  kwargs[\"old\"].valueOr\u003cint\u003e(0)\n\n  // kwargs[\"name\"].hasValue()\n  // 等效于\n  // if 'name' in kwargs\n  ```\n\n\u003c/details\u003e\n\n\n### 应用在类的构造函数中\n\n```cpp\nstruct Font\n{\n  std::string faceName;\n  int size;\n  float escapement;\n  bool italic;\n\n  // Or Kwargs\u003c\u003e kwargs = {} without checking.\n  Font(Kwargs\u003c\n    \"faceName\"_opt, /* Or */ \"name\"_opt,\n    \"size\"_opt,\n    \"escapement\"_opt,\n    \"italic\"_opt, /* Or */ \"i\"_opt\u003e kwargs = {})\n\n      : faceName(kwargs[\"faceName\"_opt or \"name\"].valueOr\u003cstd::string\u003e())\n\n      , size(kwargs[\"size\"].valueOr\u003cint\u003e(9))\n\n      , escapement(kwargs[\"escapement\"].valueOr\u003cfloat\u003e(0.00f))\n      \n      , italic(kwargs[\"italic\"_opt or \"i\"].valueOr\u003cbool\u003e(false))\n  { }\n};\n```\n\n以下构造 `Font` 的方式都是有效的：\n\n- `Font()`\n  - 同等于： `Font{ std::string(), 9, 0.00f, false }`\n\n- `Font({ })`\n  - 同等于： `Font{ std::string(), 9, 0.00f, false }`\n\n- `Font({ {\"name\", \"Arial\"}, {\"italic\", true} })`\n  - 同等于： `Font{ std::string(\"Arial\"), 9, 0.00f, true }`\n\n- `Font({ {\"italic\", \"true\"}, {\"name\", \"Arial\"} })`\n  - 同等于： `Font{ std::string(\"Arial\"), 9, 0.00f, true }`\n\n- `Font({ {\"i\", \"True\"}, {\"faceName\", \"Arial\"} })`\n  - 同等于： `Font{ std::string(\"Arial\"), 9, 0.00f, true }`\n\n- `Font({ {\"size\", 18}, {\"escapement\", 45} })`\n  - 同等于： `Font{ std::string(), 18, 45.00f, false }`\n\n- `Font({ {\"size\", \"18\"}, {\"escapement\", \"49.2\"} })`\n  - 同等于： `Font{ std::string(), 18, 49.20f, false }`\n\n- `Font({ {\"size\", 18.8}, {\"escapement\", 49.2}, {\"i\", 't'} })`\n  - 同等于： `Font{ std::string(), 18, 49.20f, true }`\n\n\u003cdetails\u003e\n\n\u003csummary\u003e\n    \u003ch3\u003e\n        简单示例：Python 和 C++ 中的 \u003ccode\u003eprintList()\u003c/code\u003e\n    \u003c/h3\u003e\n\u003c/summary\u003e\n\n- In Python\n  ```py\n  def printList(value: list, /, *, sep = ', ', end = '\\n'):\n\n    if len(value) == 0:\n      return\n\n    for i in range(len(value) - 1):\n      print(value[i], end=sep)\n\n    print(value[-1], end=end)\n  ```\n\n- In C++\n  ```cpp\n  void printList(\n    const std::vector\u003cint\u003e\u0026 value,\n    Kwargs\u003c\"sep\"_opt, \"end\"_opt\u003e kwargs = { })\n  {\n    if (value.empty())\n      return;\n\n    for (std::size_t i = 0; i \u003c value.size() - 1; ++i)\n      std::cout \u003c\u003c value[i],\n      std::cout \u003c\u003c kwargs[\"sep\"].valueOr\u003cstd::string_view\u003e(\", \");\n\n    std::cout \u003c\u003c value.back();\n    std::cout \u003c\u003c kwargs[\"end\"].valueOr\u003cstd::string_view\u003e(\"\\n\");\n  }\n  ```\n\n调用：\n\n- In Python\n  ```py\n  printList([1, 4, 3, 3, 2, 2, 3], sep=' | ', end='.')\n  ```\n\n- In C++\n  ```cpp\n  printList(\n    {1, 4, 3, 3, 2, 2, 3},\n    { {\"sep\", \" | \"}, {\"end\", '.'} });\n  ```\n\n\u003c/details\u003e\n\n在 [![EXAMPLES-MORE](https://img.shields.io/badge/EXAMPLES-MORE-gold?style=plastic\u0026logo=openbugbounty\u0026logoColor=white\u0026logoSize=auto\u0026labelColor=orange)](https://github.com/huanhuanonly/cpp-kwargs/blob/main/test.cpp) 中可以看到更多的使用方式。\n\n## 导入到自己的项目中\n\n### 克隆该仓库\n```git\ngit clone https://github.com/huanhuanonly/cpp-kwargs.git\n```\n\n### 在 _CMakeList.txt_ 中配置\n- CMakeList.txt\n```cmake\nset (CPP_KWARGS_REPOS \"https://github.com/huanhuanonly/cpp-kwargs.git\")\nset (CPP_KWARGS_PATH \"${CMAKE_SOURCE_DIR}/cpp-kwargs\")\n\ninclude (FetchContent)\n\nif (NOT EXISTS ${CPP_KWARGS_PATH})\n\tFetchContent_Declare (\n        CppKwargs\n        GIT_REPOSITORY ${CPP_KWARGS_REPOS}\n        GIT_TAG main\n        GIT_SHALLOW TRUE\n        SOURCE_DIR ${CPP_KWARGS_PATH}\n    )\n\n    FetchContent_MakeAvailable (CppKwargs)\nendif()\n\ninclude_directories (${CPP_KWARGS_PATH})\n```\n\n- main.cpp\n```cpp\n#include \u003cCppKwargs.h\u003e\n```\n\n\u003e [!TIP]\n\u003e 该项目只需要一个头文件即可运行。\n\n### 设置 `KwargsKey` 不区分大小写\n\n* 在 `#include \"CppKwargs.h\"` 前定义 `KWARGSKEY_CASE_INSENSITIVE`：\n  ```cpp\n  #ifndef KWARGSKEY_CASE_INSENSITIVE\n  #  define KWARGSKEY_CASE_INSENSITIVE\n  #endif\n  \n  #include \"CppKwargs.h\"\n  ```\n\n* 或者,在你的项目中的 _CMakeList.txt_ 文件中添加以下行：\n  ```cmake\n  target_compile_definitions (YourExecutable PRIVATE KWARGSKEY_CASE_INSENSITIVE)\n  ```\n\n## 支持的内置类型自动转换\n\n- 所有的整型和浮点型之间的互相转换。\n\n- 对于所有枚举类型 `enum` 视为其底层类型（整型）。\n\n\u003e [!TIP]\n\u003e 即使 `enum` 的底层类型是 `char` / `uchar`，它也会作为一个整型（`std::int8_t` / `std::uint8_t`）。\n\n- `std::string` $\\longleftrightarrow$ `std::string_view`。\n\n- `std::string` / `std::string_view` $\\longleftrightarrow$ `const char*`。\n\n- `std::vector\u003cchar\u003e` / `std::array\u003cchar\u003e` / `std::string_view` $\\longrightarrow$ `const char*`（并不保证有 `\\0` 结束符）。\n\n- `const char*` / `std::string` / `std::string_view` $\\longrightarrow$ `Integer` / `Floating point`。\n\n- `Integer` / `Floating point` $\\longrightarrow$ `std::string`。\n\n- `const char*` / `std::string` / `std::string_view` $\\longleftrightarrow$ `char` / `uchar`（取首字符，空则返回 `\\0`）。\n\n- `bool` $\\longrightarrow$ `const char*` / `std::string` / `std::string_view`（`\"true\"` or `\"false\"`）。\n\n- `\"true\"` / `\"True\"` / `\"TRUE\"` / `'t'` / `'T'` $\\longrightarrow$ `true`。\n\n- `\"false\"` / `\"False\"` / `\"FALSE\"` / `'f'` / `'F'` $\\longrightarrow$ `false`。\n\n- 可迭代的容器（拥有 `.begin()`、`.end()` 和 _前向迭代器_） $\\longrightarrow$ 可插入的容器。\n\n\u003e [!NOTE]\n\u003e 两个容器必须都要包含 `::value_type` 类型，值类型不需要一致，不一致时将按照以上规则进行转换。\n\n\u003cdetails open\u003e\n  \u003csummary\u003e\u003cb\u003e\u003ci\u003e可插入的容器\u003c/i\u003e\u003c/b\u003e\u003c/summary\u003e\n  拥有以下成员函数之一（按顺序）：\n\n  1. `.append()`\n  2. `.push_back()`\n  3. `.push()`\n  4. `.insert()`\n  5. `.push_front()`\n\n\u003c/details\u003e\n\n---\n\n- Copyright $2024\\text{-}2025$ [Yang Huanhuan](https://github.com/huanhuanonly) (3347484963@qq.com). All rights reserved.\n\n- Created by [Yang Huanhuan](https://github.com/huanhuanonly) on $December$ $29, 2024, 14:40:45$.\n\n- Goodbye $2024$, ***Hello*** $2025$ !","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhuanhuanonly%2Fcpp-kwargs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhuanhuanonly%2Fcpp-kwargs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhuanhuanonly%2Fcpp-kwargs/lists"}