[英]C++ 11 get pointer of a std::function
我想在std::map
存儲和標識std::function
對象。 要識別我想使用std::function::target
。 如果我使用std::bind
從類綁定到成員函數,則無法從std::function::target
獲取指針。
#include <functional>
#include <iostream>
using namespace std;
void normal_fun(int a)
{
std::cout << "hello\n"<<a;
}
class testclass
{
public:
int b;
void mytest(int a)
{
b = a;
}
};
uintptr_t getFuncAddress(std::function<void(int)> &f)
{
uintptr_t returnAddress = reinterpret_cast<uintptr_t>(f.target<void(*)(int)>());
return returnAddress;
}
int main()
{
testclass c;
std::function<void(int)> f1 = bind(&testclass::mytest,&c, placeholders::_1);
std::function<void(int)> f2 = normal_fun;
auto addrF1 = getFuncAddress(f1);
auto addrF2 = getFuncAddress(f2);
}
我該如何實現自己的目標?
std::function
不是函數指針。 它甚至都不是指針。
如果您知道std::function
存儲了什么類型,則可以獲取指向它存儲內容的指針。 請注意,此處的指針不是函數指針,而是指向函數指針的指針。
如果您不知道它存儲什么類型,就不能。
如果要<
或==
或hash
(等), std::function
不會為您提供此std::function
。 它鍵入擦除()
,復制,移動,銷毀,typeid和回退到原始。
您可以使用類型擦除技術來通過這些操作擴展std::function
; 請注意,二進制操作的類型擦除比一般的類型擦除要難一些。
解決問題時,鍵入擦除東西不應該是您的第一選擇,但它可以解決您的問題。 在C ++的SO文檔中有關於類型擦除的文章。 這不是初學者。
賠率是您可以用更簡單的方法解決的根本問題。
無論如何,使用從target
返回到順序的類型不是一個好主意,因為它是指向可能是自動存儲對象或可能是堆存儲對象的指針。 在無害操作(例如移動)下,這兩個將具有明顯不同的失效規則。 一個SBO(小型緩沖區優化)目標將與std::function
的實例一起移動,而分配了堆的目標可能保持std::function
在std::move
類似操作下std::move
的狀態。 。 這真是一團糟。
std::function
是為符合給定簽名的可調用對象提供統一的接口和類型。 您期望它還提供用於排序的統一密鑰,但它不會這樣做。 無法對std::bind
返回的函數指針和任意函數對象以及可調用對象進行排序。 它們是完全不同的東西,將它們進行比較是沒有意義的。 所有std::function
允許您做的就是存儲它們並調用它們。
如果需要排序機制,則必須自己發明一些東西,而不會從std::function
獲得它。
f.target<void(*)(int)>
這是錯誤的,因為bind返回的類型不是void(*)(int)
,所以目標永遠不會返回非null指針。 綁定不返回函數指針。 它返回一些實現指定類型的對象。
可以使用decltype
獲取類型。 這有點反常,但應該是正確的:
f.target<decltype(bind(
&testclass::mytest,
(testclass*)nullptr,
placeholders::_1)
)>
但是我有問題,如果我有testclass或myOtherClass或其他類,我在getFuncAddress中不知道
如果您知道包裝對象的類型,則只能使用std::function::target
。 如果選擇的數量有限,則可以嘗試獲取每種類型的目標,直到返回非null為止。 對於任意未知類型, std::function::target
對您沒有任何用處。
我想在std :: map中存儲和標識std :: function對象
我認為您將必須使用一些無法從std::function
提取的外部密鑰。 這意味着,如果希望防止重復,則還需要一種外部方法來保證從鍵到函數的唯一映射。
我想在std :: map中存儲和標識std :: function對象。
我假設,您要標識std::function
對象(例如,有選擇地調用或刪除它們)。 在這種情況下,我將使用其他密鑰,例如簡單的unsigned
。 可以使用全局函數:
typedef unsigned Key;
Key genId()
{
static Key id = 0;
return ++id;
}
現在,可以將std::function
對象與此鍵配對。 API可以授予對配對的std::function
對象的訪問權限,而只能使用該密鑰。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.