5

I have a class defined as

class modify_field 
{
    public:
        std::string modify(std::string str)
        {
            return str;
        }

};

Is there any way to store this function name inside a string in main function and then call it. I tried this but it's not working.

int main()
{
modify_field  mf;
std::string str,str1,str2;
str = fetch_function_name(); //fetch_function_name() returns string modify
str2 = "check";
cout << str; //prints modify
str1 = str + "(" +str2 + ")";
mf.str1(); 
}

I know this is wrong. But I just want to know if there is any way to call a function name using variable.

4

6 回答 6

7

这在 C++ 中是无法直接实现的。C++ 是一种编译语言,因此可执行文件中不存在函数和变量的名称 - 因此代码无法将您的字符串与函数的名称相关联。

您可以通过使用函数指针获得类似的效果,但在您的情况下,您也尝试使用成员函数,这会使事情变得有点复杂。

我将举一个小例子,但想在我花 10 分钟编写代码之前得到答案。

编辑:这里有一些代码来说明我的意思:

#include <algorithm>
#include <string>
#include <iostream>
#include <functional>

class modify_field 
{
public:
    std::string modify(std::string str)
        {
            return str;
        }

    std::string reverse(std::string str)
        {
            std::reverse(str.begin(), str.end());
            return str;
        }
};


typedef std::function<std::string(modify_field&, std::string)> funcptr;


funcptr fetch_function(std::string select)
{
    if (select == "forward")
        return &modify_field::modify;
    if (select == "reverse")
        return &modify_field::reverse;
    return 0;
}



int main()
{
    modify_field mf;

    std::string example = "CAT";

    funcptr fptr = fetch_function("forward");
    std::cout << "Normal: " << fptr(mf, example) << std::endl;

    fptr = fetch_function("reverse");
    std::cout << "Reverse: " << fptr(mf, example) << std::endl;
}

当然,如果你想将函数存储在 amap<std::string, funcptr>中,那是完全有可能的。

于 2013-08-26T10:40:50.503 回答
3

你有两个选择:

1 - 手动创建一个映射,其中包含指向所需函数的指针及其标识符作为字符串键,以便您可以执行查找,或者..

2 - 创建一个动态链接库/共享对象并使用名称查找来获取指针。使用 extern "C" 禁止标识符修改。您可能无法使用某些 C++ 功能并且性能会稍差,具体取决于您的实际使用场景。

于 2013-08-26T10:52:59.423 回答
2

使用 C 函数当然可以,但对于 C++ 来说确实很棘手且不可移植 - 因为不同的操作系统(甚至同一操作系统上的不同编译器)对 C++ 使用不同的 ABI,所以真正的函数名称与你在你的代码。

如果 C 函数没问题(例如,您可以将它们声明为 extern "C"),您可以将 dlsym 用于 POSIX 操作系统,将 GetProcAddress 用于 Windows。当然,您需要将此函数添加到动态符号表中 - 类似于 ld 的“-rdynamic”标志或 Windows 上的 __declspec(dllexport) (希望这是正确的 - 如果很长时间没有使用)。

于 2013-08-26T10:45:52.117 回答
1

也许指向这个函数的指针更合适。它使您可以轻松地在要调用的函数之间进行选择:

#include<iostream>
using namespace std;

class modify_field
{
    public:
        std::string modify_1(std::string str)
        {
            return str;
        }
        std::string modify_2(std::string str)
        {
            return str + str;
        }
};

int main()
{
    string (modify_field::* fun_ptr) (string) = &modify_field::modify_1;
    modify_field m;
    cout << (m.*fun_ptr)("test") << endl;
    fun_ptr = &modify_field::modify_2;
    cout << (m.*fun_ptr)("test") << endl;
}
于 2013-08-26T10:41:26.887 回答
0

如果您将想要按名称查找的所有函数放在一组源文件中,然后生成一个 DLL,您可以使用dlopen()dlsym()函数来查找入口点。

如何执行此操作的示例可以dlsym()在您机器上的手册页中找到,或者您可以参考此链接

这仅适用于未损坏的函数(即使用 C++ 时您可能会遇到一些问题)。您可能必须定义这些入口点"extern C"以防止重整,或者想出一些其他机制来猜测 C++ 入口点的重整名称。我从来没有做过后者,所以肯定会有一些我没有注意到的细微差别。

如果您使用的是 Windows(不清楚您使用的是什么操作系统),您应该在此处GetProcAddress()查找在线可用的文档。

一个很好的关于这个主题的教程,这个确实谈到了如何用 C++ 做这一切,可以在这里找到。

于 2013-08-26T11:29:37.910 回答
0

如果函数具有相同的签名,您可以创建字符串到 std::function 对象的映射。在此处查看有关 std::function 的更多信息:std::function

于 2013-08-26T10:45:06.320 回答