我想实现一个C++命令行通用参数解析器(也是为了好玩)。现有的流行参数解析器缺乏一些功能。
*gflags:不太支持向量。
*getopt:基于C,用于无类型。
我想要一个可以处理任意类型的泛型参数解析器,如下所示:
class YourArgument {
vector<int> your_ints;
string my_str;
bool help;
};
YourArgument your_arg;
Argparse(your_arg, argv, argc); // A template
这个Argparse
可以处理类似"./run --help --my_str string --your_ints 1 2 3 run.txt"
的东西。
我发现像C++17结构绑定这样的东西可以实现这样的实现。如果我们能够为一个类添加一些getter,那么我们可以如下实现它。
class YourArgument {
vector<int> your_ints;
string my_str;
bool help;
auto& get(integral_constant<int, 0>) { return your_ints; }
auto& get(integral_constant<int, 1>) { return my_str; }
auto& get(integral_constant<int, 2>) { return help; }
const char* getstr(int i) {
if (i == 0) return "your_ints";
if (i == 1) return "my_str";
if (i == 2) return "help";
}
};
template <typename T>
void Argparse_impl(T& your_arg, const char **argv, int &argc, int &c) {
// Common recursive implementation
// Skipped here
Argparse_impl<i+1>(your_arg, argv, argc, c);
}
template <typename T>
void Argparse(T& your_arg, const char **argv, int &argc) {
int c = 0;
while (c < argc) Argparse_impl<0>(your_arg, argv, argc, c);
}
解析器实现本身就是一个普通的递归技巧,这不是我需要建议的部分。我的问题是有没有办法用宏生成样板?
我试过这个实现,代码大致看起来像这样(不是我使用的确切代码)。然而,它大大延长了我的编译性能。我有很多这样的类要编译,结构体非常长。
#define MY_MACRO(...)\
auto& get_tuple() { return forward_as_tuple(__VA_ARGS_); }\
template<unsigned i> auto& get() { return get<i>(get_tuple()); }\
const char* getstr() { static string strs = string(##__VA_ARGS_).split(); return strs[i]; }\
1条答案
按热度按时间gwbalxhn1#
虽然我恐怕我没有一个关于如何改进你的解决方案的建议,但似乎你正在寻找的功能是完全可能的,而不使用宏的使用C++ argparse库https://github.com/morrisfranken/argparse。它支持向量,一切都表示在一个结构中。这里是一个例子,你可以如何使用它为你的例子
您可以使用以下命令运行此示例:
免责声明:我是图书馆的作者