2016-08-03 205 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 –

相关问题