![](/img/trans.png)
[英]C++11 auto, std::function and ambiguous call to overloaded function
[英]use std::string to call a function in C++11
我想使用字符串值來調用 function。這可能嗎? 有人可以展示一些實現嗎? 我會很感激。
class obj {
int num1;
int num2;
}
int func1(obj o) {
return o.num1 + o.num2;
}
// This is an example data set. This map would be populated with values in the map below with some piece of code.
std::map<std::string, std::string> funcNameMap = {{"func1", "func1"}};
int someFunction(std::string funcName, obj o) {
// Get the value associated with the string "funcName" i.e. "func1".
// Calls function "func1" with value "o" and returns the value.
}
int main(){
obj o;
o.num1 = 1;
o.num2 = 2;
auto x = someFunciton("func1", o);
std::cout << x << std::endl;
return 0;
}
我正在編寫一個收集指標數據的程序。 我想針對特定指標執行特定的 function。 我會將所有函數命名為與度量名稱相同,這樣當我將度量名稱作為輸入(字符串)時,它將執行特定的 function。我不希望 if-else 根據作為我的程序輸入的度量名稱執行 function正在收集一百多個指標。 如果使用 may if-else 看起來會很尷尬。 這就是為什么我試圖以這種方式做某事。
想要適用於兩種操作系統 windows/linux 的東西
一種解決方案是創建從 function 名稱到 function 本身的映射。 我們知道function在C/C++中是一個指針,所以我們在確認function指針的類型后就可以很容易的做到這一點。 在您的情況下,目標 function 類型是int (*)(obj)
。
代碼片段:
#include <iostream>
#include <map>
#include <string>
class obj {
public:
int num1;
int num2;
};
int func1(obj o) { // type: int (*)(obj)
return o.num1 + o.num2;
}
// create the mapping from name to function
std::map<std::string, int (*)(obj)> funcNameMap = {{"func1", func1}};
int someFunction(std::string funcName, obj o) {
// Get the value associated with the string "funcName" i.e. "func1".
// Calls function "func1" with value "o" and returns the value.
auto fn = funcNameMap.at(funcName);
return fn(o);
}
int main(){
obj o;
o.num1 = 1;
o.num2 = 2;
auto x = someFunction("func1", o);
std::cout << x << std::endl;
return 0;
}
編輯:根據評論更新,使用動態共享庫避免手動創建映射。 我假設您使用的是 Linux。
首先,將 class 定義和目標函數類型移動到單獨的 header obj.hpp
:
class obj {
public:
int num1;
int num2;
};
// type of target functions
typedef int (*ftype)(obj);
將目標函數收集到單獨的文件functions.cpp
以構建動態共享庫。
#include "obj.hpp"
extern "C"
int func1(obj o) {
return o.num1 + o.num2;
}
extern "C"
int func2(obj o) {
return o.num1 - o.num2;
}
在第三個文件main.cpp
中,我們根據 function 名稱從庫中檢索函數。
#include <iostream>
#include <map>
#include <dlfcn.h>
#include <cassert>
#include "obj.hpp"
// name mapping: public name to inner name
std::map<std::string, std::string> funcNameMap = {{"add", "func1"}, {"sub", "func2"}};
int retrieve_fn(void *dl_handler, std::string funcName, obj o) {
assert(dl_handler != NULL && funcNameMap.count(funcName) != 0);
auto real_fn_name = funcNameMap[funcName];
auto fn = (ftype)dlsym(dl_handler, real_fn_name.c_str());
auto dl_err = dlerror();
if (dl_err) {
std::cerr << "Load failed: " << dl_err << std::endl;
return -999;
}
return fn(o);
}
int main(){
obj o;
o.num1 = 1;
o.num2 = 2;
// open dynamic shared library
auto dl_name = "./functions.so";
auto dl_handler = dlopen(dl_name, RTLD_LAZY);
auto dl_err = dlerror();
if (dl_err) {
std::cerr << "Open failed: " << dl_err << std::endl;
return -1;
}
auto x = retrieve_fn(dl_handler, "add", o);
std::cout << x << std::endl;
x = retrieve_fn(dl_handler, "sub", o);
std::cout << x << std::endl;
dlclose(dl_handler);
return 0;
}
functions.cpp
構建一個動態共享庫。$ g++ functions.cpp -shared -fPIC -o functions.so
main.cpp
構建一個可執行文件。$ g++ main.cpp -ldl -o main
$ ./main
3
-1
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.