我正在尝试但是当我将派生类的函数成员指针作为模板参数传递时,我不知道如何(但可能不可能)捕获相同的类型类。
例如,拥有这段代码,
class CObject{
public:
string m_id;
void setID(const char * id){
printf("assign id %s\n",id);
m_id=string(id);
}
~CObject(){}
};
class CDerivedObject:public CObject{
public:
~CDerivedObject(){};
};
使用此功能模板,
template < typename _R, class _T, typename..._A>
void function_template_test(_R (_T:: *function_type)(_A...) )
{
printf("ObjectTypeIs: %s\n",typeid( _T).name());
}
在main函数中我调用function_template_test传递函数指针成员CDerivedObject :: setID,
function_template_test(&CDerivedObject::setID);
如果我使用g ++编译此代码(我的上一个版本是5.4.0),则打印 7CObject ,这意味着_T是CObject类型,但在参数中我传递了 CDerivedObject :: setID。我知道函数setID函数属于CObject,因此编译器会以这种方式获取类型,但是......
有没有办法捕获我传递模板参数的类类型(即_T是CDerivedObject)?
编辑1
我的问题的解决方案可能是这个,
template < class _C, class _R, typename _T, typename..._A>
void _function_template_test(_R (_T:: *function_type)(_A...) )
{
printf("ObjectTypeIs: %s\n",typeid( _C).name());
}
#define function_template_test(cl, fun)\
_function_template_test<cl>(&cl::fun)
然后我将该函数称为
function_template_test(CDerivedObject,setID);
是一个解决方案,但我更喜欢模板而不是宏。
答案 0 :(得分:2)
考虑这个程序:
struct Base { void foo() {} };
struct Derived: Base {};
auto main() -> int
{
int x = &Derived::foo;
}
这是使用MinGW g ++进行编译的结果:
[H:\forums\so\056] > g++ main.cpp main.cpp: In function 'int main()': main.cpp:6:23: error: cannot convert 'void (Base::*)()' to 'int' in initialization int x = &Derived::foo; ^~~ [H:\forums\so\056] > _
正如您所看到的,&Derived::foo
的类型是void (Base::*)()
(是的,根据标准,这是
即,当你问
时“是否有可能捕获类型I&m;传递模板参数的方法
......这就是你正在做的事情。
要使该类型为void (Derived::*)()
,您需要在Derived
中声明一个函数。
对于调用带有成员函数指针的函数的情况,您也可以显式指定所有模板参数。这是有效的,因为void (Base::*)()
会隐式转换为void (Derived::*)()
。是的,这是违反直觉的,并且在C ++类型系统中构成了一个小小的漏洞,但是当您考虑可以调用成员函数的类型对象时,它就是逻辑运行的方式。
重新开环,这是一个例子(见ma,没有演员表!):
#include <iostream>
#include <stack>
using namespace std;
auto main()
-> int
{
stack<int> st;
for( int const i : {1, 2, 3} ) { st.push( i ); }
struct Hack: stack<int> { using stack<int>::c; };
int const n = (st.*&Hack::c).size();
cout << "That stack contains " << n << " items." << endl;
}