簡體   English   中英

調用const函數指針

[英]Calling Const function pointer

首先,我想提一下,這適用於MSVC,但不適用於clang。 我在C ++ 11中使用Clang。

我有一個函數指針:

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從'const void '到'void( )(const char *,const char *,const char *,int)'取消了行的限定符:reinterpret_cast(m_functions [i])(title,cause,file,line);

據我了解,我正在嘗試將函數的const列表轉換為非const值。 這是不允許的,這是有道理的。 所以我嘗試了以下方法:

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 cast。 我究竟做錯了什么? 我怎么稱呼這個const函數? 還是因為它不知道被調用的函數是否為const函數而被完全禁止使用? 還是因為我的靜態函數不是類的成員,所以不能將其聲明為const?

您將函數指針存儲為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);

暫無
暫無

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

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