1

假设我只想在我的代码中调用一个函数:func(),但根据我给它的值,它是否直接指向该函数的正确“版本”?

我知道这可能与 if-statements/switch-statements 相关,但是它必须(低效地)检查传递了哪个值。我希望有一种预编译的方式来做到这一点?

这样的事情有可能以一种有效的方式进行吗?

func(3)

将执行第三版 func()

func[1]{
    cout "One";
}

func[2]{
    cout "Two";
}

func[3]{
    cout "Three";
}
4

6 回答 6

6

你可以有一个函数指针数组:

int foo_1() {
   cout << "One";
}

// ...

auto[] functions = {foo_1, foo_2, foo_3};

并调用它

 functions[0]();
于 2013-04-17T04:58:14.313 回答
2

实际上,case-switch 非常有效,因为即使您有非常多的目标,它也可以在代码中将其编译为跳转表,而不是 if 链 - 所以 switch 的所有部分都将是等量的指令。

http://en.wikipedia.org/wiki/Switch_statement#Compilation

如果输入值的范围可以识别为“小”并且只有几个间隙,则某些包含优化器的编译器实际上可能将 switch 语句实现为分支表或索引函数指针数组,而不是冗长的一系列条件指令。 * 这允许 switch 语句立即确定要执行的分支,而无需通过比较列表。

此外:

1) 如果您没有将代码识别为减慢程序速度的瓶颈,请不要担心过早优化。

2)为什么调用具有不同值的函数会使其做完全不同的事情?不应该是不同的功能吗?(如果你想在一个循环中调用一堆函数,你总是可以创建一个函数指针数组 - 查找函数指针)

于 2013-04-17T04:56:59.623 回答
0

当你这样做func(3)时,参数是常量,如果没有副作用,编译器将自动优化函数。这意味着函数不能修改全局变量、成员变量或写入传递给函数的任何指针。语句将if在运行时消失。

于 2013-04-17T04:56:55.787 回答
0

我相信可以为此使用模板化函数。

例如

template< int subfunc>
void func< subfunc>();

void func<1>();

像这样的东西应该工作:)

这样,当你调用它时,你会说:func<1>();它会调用另一个函数。

刚查了一下。此解决方案不会按照用户的意愿工作,因为在 V 形中输入的值必须是常量/编译时解析的值。

于 2013-04-17T04:58:36.607 回答
0

由于我们在这里使用 C++ 是硬汉,我会使用mapfrom string(您的输入)to void *(表示所有函数),这样我就不需要依赖映射中可调用函数的任何特定顺序。我也不需要将输入转换为数字(如果输入来自控制台并且是字符串)

#include <map>
#include <string>
#include <iostream>     // for cout

using namespace std;    // that's the way I like it

int main()
{
    map<string, void *> funcs;

    funcs["func1"] = (void *)func1;
    funcs["func2"] = (void *)func2;
    ...

    string s = myinput();
    if (funcs.find(s) != funcs.end()) {
        ((void (*)())funcs[s])();   // call the function (first casting it to the function's data type
    }
    else cout << "### Error: function " << s << " doesn't exist in map" << endl;

    return 0;
}
于 2013-04-17T05:16:39.653 回答
-1

您可以使用值模板来做到这一点。但如果你这样做,为什么还要有一个函数呢?为什么不只是有 N 个不同命名的函数,在维护代码时它会更容易混淆。

于 2013-04-17T04:56:52.860 回答