簡體   English   中英

C ++ 11獲取std :: function的指針

[英]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::functionstd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM