函数作为模板参数的问题
Functions as template parameters issue
我有一个问题困扰着我。我有一个FSM类,它将键关联到回调
class FSM
{
public:
typedef bool (FSM::*InCallback_t)( int );
typedef std::map< std::string, InCallback_t > Table;
// Since I would like to allow the user to register both functors and class member functions
template< typename Callback_t, bool (Callback_t::*CallbackFunct_t)(int) >
bool callback( int x )
{
return (Callback_t().*CallbackFunct_t)( x );
}
void addCallback( const std::string& iKey, InCallback_t iCallback )
{
_table.insert( std::make_pair( iKey, iCallback ) );
}
[ ... ]
private:
Table _table;
};
和一些回调类
class CallbackBase
{
public:
bool operator()( int x ){ return doCall( x ); }
private:
virtual bool doCall( int x ){ return true; }
};
class Callback: public CallbackBase
{
private:
bool doCall( int x )
{
std::cout << "Callbackn";
return true;
}
};
现在进入主目录:
FSM aFSM;
// OK
aFSM.addCallback( "one", &FSM::callback< CallbackBase, &CallbackBase::operator() > );
// KO
aFSM.addCallback( "two", &FSM::callback< Callback, &Callback::operator() > );
第一个调用没有问题,第二个调用编译器会报错:
Test.cpp: In function ‘int main(int, char**)’:
Test.cpp:104:77: error: no matching function for call to ‘FSM::addCallback(const char [4], <unresolved overloaded function type>)’
Test.cpp:104:77: note: candidate is:
Test.cpp:24:7: note: void FSM::addCallback(const string&, FSM::InCallback_t)
Test.cpp:24:7: note: no known conversion for argument 2 from ‘<unresolved overloaded function type>’ to ‘FSM::InCallback_t’
还需要注意的是:
typedef bool (Callback::*Function_t)( int );
Function_t aFunction = &Callback::operator();
(Callback().*aFunction)( 5 );
任何想法?提前感谢您的帮助。
西蒙
您没有定义Callback::operator()。没有第二个Callback函数,只有一个来自CallbackBase的函数,它接受一个CallbackBase和一个int作为参数!这就是为什么编译器会抱怨"未解析的重载函数类型"。
继承函数的类型为bool (CallbackBase::*operator())(int)。这个函数可以自动转换为bool (Callback::*operator())(int),因为您总是可以将Callback应用于只接受CallbackBase的函数。这就是为什么下面的工作-这是一个自动转换发生在那里。
typedef bool (Callback::*Function_t)( int );
Function_t aFunction = &Callback::operator();
问题出现在模板类型推导中:
template< typename Callback_t, bool (Callback_t::*CallbackFunct_t)(int) >
with: Callback_t = Callback, CallbackFunct_t = bool (CallbackBase::*CallbackFunct_t)(int)
这不起作用,因为在实例化回调函数时,通过Callback_t给出的类型与函数指针所需的类型不匹配。在进行类型推导之前,可以将函数指针显式强制转换为(Callback::*operator())(int)来解决这个问题。如果您将回调函数更改为以下类型,则不需要两种类型相同,并且它编译时不需要强制转换。
template< typename Callback_t>
bool callback( int x )
{
return Callback_t()( x );
}
我不明白的是你为什么要加虚函数。下面的代码不是也一样吗?更简单,可读性更强,甚至更快(没有虚函数调用)?doCall函数必须是公共的。
template< typename Callback_t>
bool callback( int x )
{
return Callback_t().doCall( x );
}
另一个改进是使回调函数成为静态的。如果doCall函数是静态的,那就更简单了——这将使回调函数过时,并避免创建临时调用doCall。
相关文章:
- C++复杂情况的比较器通过参数问题
- C++17 中的歧义错误(模板模板参数和默认参数问题)
- C 缺少模板参数问题
- C++ pcap_loop() 参数问题
- 带有指针作为参数问题的 C++ 函数
- C++ 奇怪的字符*参数问题(不兼容的类型)
- JNA 参数问题:内存访问无效
- Qt样式表和"一个参数"问题
- 默认参数问题 (c++)
- 具有可变模板的递归继承和继承参数问题
- 命令行参数问题
- OpenCV 决策树参数问题
- winapi GetProcessMemoryInfo 无效参数问题
- 参数问题?至少我认为是这样
- 构造函数参数问题C++
- c++教程参考参数问题
- c++多线程参数问题
- Clang Format多行函数声明参数问题
- 提升Python - 具有默认参数问题的重载函数
- VBA Excel DLL参数问题-第6个参数