2016-08-03 117 views
0

首先我想提一下,這適用於MSVC,但不適用於鏗鏘聲。我正在使用C++ 11的Clang。調用Const函數指針

我有一個函數指針:

typedef void (*Log) (const char* title, const char* msg, const char* file, int line); 

我有這樣的結構:

struct FunctionList 
    { 
    protected: 
     static const int kNbrMax = 32; 
     FunctionList(); 
     bool Add(const void* f); 
     bool Remove(const void* f); 

     const void*  m_functions[kNbrMax]; 
    }; 

這個類:

template<typename T> 
struct MessageFunctionList 
    : public FunctionList 
{ 
public: 
    MessageFunctionList(T defaultFunction) 
    { 
     Add(defaultFunction); 
    } 

    void Call(const char* title,const char* cause,const char* file,int line) 
    { 
     for (unsigned long i = 0;i < m_nbrUsed;++i) 
     { 
      reinterpret_cast<T>(m_functions[i])(title,cause,file,line); 
     } 
    } 
} 

我創造它像這樣:

static void DefaultLogMessageFunction(const char* title,const char* msg,const char* file,int line) 
{ 

} 

MessageFunctionList<Log> functionList(DefaultLogMessageFunction) 

但我得到的編譯時錯誤:

reinterpret_cast from 'const void ' to 'void ()(const char *, const char *, const char *, int)' casts away qualifiers for line: reinterpret_cast(m_functions[i])(title,cause,file,line);

所以據我瞭解,我想投我的功能常量列表非常量值。這是不允許的,這是有道理的。所以我嘗試了以下內容:

const void* funcPtr = m_functions[i]; 
const T call = reinterpret_cast<const T>(funcPtr); 
call(title, cause, file, line); 

但是這也行不通。

這工作:

void* funcPtr = const_cast<void*>(m_functions[i]); 
T call = reinterpret_cast<T>(funcPtr); 
call(title,cause,file,line); 

但我想避免使用const的演員。我究竟做錯了什麼?我怎樣才能調用這個const函數?或者它是不允許的,因爲它不知道被調用的函數是否是const函數?也許這是因爲我的靜態函數不是一個類的成員,所以它不能被聲明爲const?

+0

請提供[MCVE。我無法分辨你在做什麼。 – Barry

+0

我錯過了什麼?包含的內容不是必需的?我想我已經包括了所需的一切?你想要一個壓縮的項目?我試圖存儲一個函數指針列表來記錄函數。 – marsh

+1

你錯過了一個MCVE。我正在尋找一個簡短的,自包含的例子,我可以看到你得到了什麼樣的編譯錯誤以及你想要做什麼。我看到的只是幾個不相關的代碼片斷,我不明白你要做什麼或者失敗的原因。 – Barry

回答

2

您存儲函數指針爲const void*

const void*  m_functions[kNbrMax]; 

而你試圖他們轉換爲T和使用reinterpret_cast稱之爲:

reinterpret_cast<T>(m_functions[i])(title,cause,file,line); 

然而,reinterpret_cast不能刪除const因此,您應該首先使用const_cast刪除const

reinterpret_cast<T>(const_cast<void*>(m_functions[i]))(title,cause,file,line); 
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 

但是,請注意,const_cast會產生未定義的行爲並且是不安全的。因此,如果原始指針實際上不是T,則調用從reinterpret_cast返回的函數指針。

編輯: 你可以調用const合格的函數指針,但是,那麼reinterpret_cast應包含const預選賽:

reinterpret_cast<const T>(m_functions[i])(title,cause,file,line); 
+0

謝謝,但我在我的帖子底部提供了同樣的解決方案。我不明白爲什麼我不能存儲和調用const函數。我試圖避免常規演員。 – marsh

+0

我試圖說,它會工作,但我得到同樣的錯誤。它很奇怪,因爲在線編譯器似乎編譯沒有錯誤。 – marsh

+0

@marsh,在線和離線g ++編譯器也是如此:http://coliru.stacked-crooked.com/a/ccf66094fb802e7d –