簡體   English   中英

如何將“const void*”轉換為 C++11 中的函數指針?

[英]How can I cast “const void*” to the function pointer in C++11?

我想將一些const void*對象轉換為函數指針:

std::unordered_map<std::string, const void*> originals_;

template <typename R, typename... Args>
R CallOriginal(const std::string& name, Args... args) {
  return reinterpret_cast<R (*const)(Args...)>(originals_[name])(args...);
}

但是,令我驚訝的是,我收到以下錯誤消息:

錯誤:從'mapped_type'(又名'const void *')到'int (*const)(int)'的reinterpret_cast拋棄了限定符

首先,使用const函數指針是否有意義? 如果是這樣,那么我如何合法地進行鑄造?

為了按名稱調用任何函數,您可以使用std::any與標准庫函子std::function結合使用

請注意,調用者必須知道簽名,例如無法推導出參數類型和返回類型。

一個例子:

#include <any>
#include <functional>
#include <string>
#include <unordered_map>

#include <iostream>

static int foo(int a, const std::string& b) {
    std::cout << "foo(" << a << ',' << b << ");" << std::endl;
    return 0;
}

static void bar(float a, const std::string& b) {
    std::cout << "bar(" << a << ',' << b << ");" << std::endl;
}

class call_function_by_name {
public:
    explicit call_function_by_name(std::unordered_map<std::string, std::any>&& table):
        table_(table)
    {}
    template <typename R,typename... ArgTypes>
    R call(const std::string& name,ArgTypes... args) const {
       typedef std::function<R(ArgTypes...)> functor_t;
       std::any anyf = table_.at(name);
       // call function by name
       functor_t functor = std::any_cast<functor_t>( anyf ) ;
       return functor( args... );
    }
private:
    std::unordered_map<std::string, std::any> table_;
};


int main(int argc, const char** argv)
{

    std::unordered_map<std::string, std::any> exportTable;
    exportTable.emplace("foo", std::function<int(int,const std::string&)>(foo) );
    exportTable.emplace("bar", std::function<void(float,const std::string&)>(bar) );

    call_function_by_name bus( std::move(exportTable) );
    int ret = bus.call<int,int,const std::string&>("foo", 1, std::string("bus foo") );
    std::cout << "Foo returned " << ret << std::endl;
    bus.call<void,float,const std::string&>("bar", 2.0F, "bus bar");

    return 0;
}

您想擦除函數簽名並僅存儲函數指針。

為此,您可以將函數指針轉換為其他函數指針,例如typedef void(*p)()

C++ 可以在數據存儲器和代碼存儲器不交互且具有不同指針大小的體系結構上工作。 所以將函數指針轉換為數據指針一般是不安全的

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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