使用包含函数名称的字符串调用函数
Calling a function using a string containing the function's name
我有一个定义为的类
class modify_field
{
public:
std::string modify(std::string str)
{
return str;
}
};
有没有任何方法可以将这个函数名存储在main函数的字符串中,然后调用它。我试过了,但不起作用。
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();
}
我知道这是错误的。但我只想知道是否有任何方法可以使用变量调用函数名。
这在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;
}
当然,如果您想将函数存储在map<std::string, funcptr>
中,那么这是完全可能的。
您有两个选择:
1-手动创建一个映射,其中包含指向所需函数的指针及其标识符作为字符串键,这样您就可以执行查找,或者。。
2-创建一个动态链接库/共享对象,并使用名称查找来获取指针。使用外部"C"来禁止标识符篡改。您可能无法使用某些C++功能,性能会稍差,具体取决于您的实际使用情况。
对于C函数来说,这当然是可能的,但对于C++来说,这将是非常棘手和不可移植的,因为不同的操作系统(甚至同一操作系统上的不同编译器)对C++使用不同的ABI,因此实际函数名与代码中对它们的命名有很大不同。
如果C函数是可以的(例如,您可以将它们声明为extern"C"),则可以对POSIX OS使用dlsym,对windows使用GetProcAddress。当然,您需要将这些函数添加到动态符号表中,比如ld的"-rdynamic"标志,或者windows上的__declspec(dllexport)(希望是对的,很久没有使用if了)。
如果函数具有相同的签名,则可以创建字符串到std::function对象的映射。有关std::function的更多信息,请点击此处:std::function
也许指向这个函数的指针更合适。它允许您在要调用的函数之间轻松选择:
#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;
}
如果将要按名称查找的所有函数放在一组源文件中,然后用这些源文件生成DLL,则可以使用dlopen()
和dlsym()
函数来查找入口点。
如何做到这一点的示例可以在您机器上dlsym()
的手册页中找到,也可以参考此链接。
这只适用于未处理的函数(即,使用C++时可能会出现一些问题)。您可能必须将这些入口点定义为"extern C"
以防止损坏,或者想出一些其他机制来猜测C++入口点的损坏名称。我从来没有做过后者,所以肯定会有一些我没有注意到的细微差别
如果您使用的是Windows(不清楚您使用的操作系统),您应该在此处查找GetProcAddress()
的文档。
关于这个主题的一个很好的教程,这个教程确实谈到了如何使用C++来完成这一切,可以在这里找到。
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何从void函数输出字符串
- 使用用户定义函数的字符串反转
- 为什么我不能在不创建字符串变量的情况下使用函数的字符串输出
- C++ 使用 assign 函数的字符串与直接使用 '=' 更改值的字符串之间的区别
- 在c++构造函数中使用随机字符串生成器
- C++浮点数据类型和字符串数据类型无法子到模板函数中
- C++:如何使函数只返回作为列表一部分的字符串
- 如何在C++中的同一函数中使用字符串和双精度
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- 使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题
- 一个函数,用于查找字符串1包含字符串2 c++的次数
- 对函数 PlaySound 使用字符串变量
- 具有多个模板的模板函数,用于特定数据类型(如字符串)?
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- Visual c ++,使用字符串引用/指针调用 dll 函数
- 构造函数字符串参数未设置窗口标题
- C++默认构造函数:字符串参数与字符串参数()
- 使用函数C++字符串输入
- c++模板函数字符串类型不匹配