C++ 中的变量参数列表和C

发布于 2024-08-06 17:11:32 字数 718 浏览 5 评论 0原文

我正在努力用 C++ 重写 C 程序,以利用 OO 方面的优势,以便它可以轻松支持多个设备,并且该程序的一部分是表达式求值器。表达式可以有函数调用,这是函数的结构。

typedef struct {
    char *name;
    int argc;
    void (*func) ();
} FUNCTION;

不知何故,func 可以传递可变数量的参数。

RESULT *param[10];

if (Root->Function->argc < 0) {
    /* Function with variable argument list:  */
    /* pass number of arguments as first parameter */
    Root->Function->func(Root->Result, argc, &param);
} else {
    Root->Function->func(Root->Result, param[0], param[1], param[2], param[3], param[4], param[5], param[6],
                         param[7], param[8], param[9]);
}

老实说,我什至不确定如何在 C 中完成此操作。一个解释会很好。可以用C++完成吗?

I'm working on rewriting a C program in C++ to take advantage of OO aspects so it can easily support multiple devices, and one part of the program is an expression evaluator. Expressions can have function calls, and here's the structure for functions.

typedef struct {
    char *name;
    int argc;
    void (*func) ();
} FUNCTION;

Somehow func can have a variable number of arguments passed through it.

RESULT *param[10];

if (Root->Function->argc < 0) {
    /* Function with variable argument list:  */
    /* pass number of arguments as first parameter */
    Root->Function->func(Root->Result, argc, ¶m);
} else {
    Root->Function->func(Root->Result, param[0], param[1], param[2], param[3], param[4], param[5], param[6],
                         param[7], param[8], param[9]);
}

I'm not even sure how this can be done in C to be honest. An explanation would be excellent. Can it be done in C++?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

◇流星雨 2024-08-13 17:11:32

var args 就是您要寻找的内容。它适用于 C 和 C++。例如,这就是 printf() 所使用的内容:)。

您可以通过谷歌搜索 va_arg(用于可变数量参数的函数之一)来查找更多信息)

The var args are what you are looking for. It works both in C and C++. This is what is used for printf() for example :).

You can find more information by googling va_arg (one of the function used for variable number of arguments)

孤独患者 2024-08-13 17:11:32

事实上,我要反对这里的每个人,以及你们的愿望。

省略号是错误的。它被认为是 C 语言中不可或缺的,但从那时起我们学得更好了。

事实上,在 C++ 中,有一些方法可以做得更好,使用对象,例如函数对象。

您正在寻找的是命令模式

创建一个名为“Command”的基类(与execute() 方法的接口),然后为要放入“void (*func)()”中的每个“函数”创建一个派生类。

现在,您的代码将如下所示:

std::vector<RESULT*> param(10, NULL);

if (Root->Function->argc < 0) {
    /* Function with variable argument list:  */
    /* pass number of arguments as first parameter */
    Command1* aCommand = new Command1(Root->Result);
    aCommand->set(Root->Result, argc, ¶m);
    Root->Function->command = aCommand;
    Root->Function->command->execute();
} else {
    Command2* aCommand = new Command2(Root->Result);
    aCommand->set(Root->Result, param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], param[8], param[9]);
    Root->Function->command = aCommand;
    Root->Function->command->execute();
}

这里您不需要省略号,因为每个命令对象都是专门的,并且确切地知道它需要的参数是什么(数字和类型)。

命令模式使您可以享受“...”(省略号)的所有好处,而不会带来不便。当然,有些人会说这是浪费时间,因为他们无论如何都不会犯错误,所以他们不需要输入更多...不幸的是我不是那么聪明,所以我更喜欢定义约束(数字,类型) 、断言)并让编译器为我强制执行它们。

Actually I am going to go against everyone here, and your desire.

Ellipsis is wrong. It was thought of as indispensable in C but we learned better since then.

Indeed, there are ways to actually much better in C++, using objects, and for example, function objects.

What you are looking for is the Command Pattern.

Create a base class called 'Command' (interface with a execute() method), then for each of the 'functions' you wanted to put in 'void (*func)()' you create a derived class.

Now, your code is going to look like that:

std::vector<RESULT*> param(10, NULL);

if (Root->Function->argc < 0) {
    /* Function with variable argument list:  */
    /* pass number of arguments as first parameter */
    Command1* aCommand = new Command1(Root->Result);
    aCommand->set(Root->Result, argc, ¶m);
    Root->Function->command = aCommand;
    Root->Function->command->execute();
} else {
    Command2* aCommand = new Command2(Root->Result);
    aCommand->set(Root->Result, param[0], param[1], param[2], param[3], param[4], param[5], param[6], param[7], param[8], param[9]);
    Root->Function->command = aCommand;
    Root->Function->command->execute();
}

Here you don't need the ellipsis because each command object is specialized and know exactly what are the parameters it needs (number AND types).

The command pattern allow you to have all the benefits of the '...' (ellipsis) without its inconvenient. Well of course some are going to say that it's a loss of time since they don't make mistakes anyway so they don't need to type more... unfortunately I am not that smart so I prefer to define constraints (number, types, assertions) and let the compiler enforce them for me.

格子衫的從容 2024-08-13 17:11:32

您可以在 C++ 中通过在参数列表中使用 ... 来完成此操作。请查看此处了解说明。但我认为如果你只将参数向量传递给你的函数会更好。

You can do it in C++ by using ... in the argument list. Take a look here for explanation. But I think it will be better if you just pass a vector of param to your function.

苍景流年 2024-08-13 17:11:32

请记住,函数只是另一个地址,当调用 start 时从堆栈中获取输入参数。因此,当您声明一个 FUNCTION 时,您只是存储该函数的地址。通过该地址,稍后可以使用不同的参数调用该函数。是的,可以通过使用参数列表在 C++ 中完成,但是实现取决于您希望它如何处理它。

Remember, a function is just another address, that when called start take input parameters from the stack. So, when you declare a FUNCTION, you are just storing the address of that function. With that address the function could be called later with the different parameters. An yes, it could be done in C++ by using argument lists, however the implementation depends on how you want it to handle it.

愁以何悠 2024-08-13 17:11:32

就我个人而言,在评估表达式的 AST 时,我倾向于使用特定于领域的语言来为我生成 AST 节点结构的层次结构和一组多重分派操作。我有自己的 DSL,但这个想法是从 treecc 窃取的。很多问题都会消失,因为您不需要单个节点类或单个评估节点函数 - 并且通过 DSL 为您执行各种检查,您基本上可以避免用不同的问题替换这些问题。

treecc 可以生成 C 或 C++ 输出(或一些其他语言)IIRC。这很像使用 flex 或 bison。生成的代码有点幼稚,您很快就会希望对继承有更多的控制,但它工作得很好。

Personally, when it comes to evaluating the AST for an expression, I tend to use a domain specific language to generate a heirarchy of AST node structs and a set of multiple-dispatch operations for me. I have my own DSL for this, but the idea was stolen from treecc. A lot of problems go away because you don't need to have a single node class or a single evaluate-node function - and with the DSL doing various checks for you, you mostly avoid replacing those problems with different ones.

treecc can generate C or C++ output (or a few other languages) IIRC. It's a lot like using flex or bison. Generated code is a bit naive and you soon end up wishing for more control over inheritance, but it works pretty well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文