获取与在模板参数中传递的函数成员类型相同的类

get the same class as function member type passed in template arg

本文关键字:成员 函数 成员类 类型 参数 获取      更新时间:2023-10-16

我正在尝试,但我不知道当我将派生类的函数成员指针作为模板参数传递时如何(但可能是不可能的)捕获相同的类型类。

例如,拥有这段代码,

class CObject{
public:
string m_id;
void setID(const char * id){
printf("assign id %sn",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: %sn",typeid( _T).name());
}

在主函数中,我调用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: %sn",typeid( _C).name());
}
#define function_template_test(cl, fun)
_function_template_test<cl>(&cl::fun)

然后我调用该函数为,

function_template_test(CDerivedObject,setID);

是一个解决方案,但我更喜欢模板而不是宏。

考虑这个程序:

struct Base { void foo() {} };
struct Derived: Base {};
auto main() -> int
{
int x = &Derived::foo;
}

以下是使用 MinGW g++ 编译的结果:

[H:\论坛\so\056]>g++main.cpp main.cpp: 在函数 'int main()' 中: main.cpp:6:23:错误:初始化时无法将"void (Base::*)()"转换为"int"  int x = &Derived::foo;  ^~~ [H:\论坛\so\056]> _

如您所见,&Derived::foo的类型是void (Base::*)()(是的,这是根据标准)。

即,当你问

">有没有办法捕获我传递模板参数的类类型

。这就是你正在做的事情。

要使该类型void (Derived::*)()您需要一个在Derived中声明的函数。


对于调用采用成员函数指针的函数的情况,也可以显式指定所有模板参数。这是有效的,因为void (Base::*)()隐式转换为void (Derived::*)()。是的,这是违反直觉的,并且在C++类型系统中构成了一个小漏洞,但是当您考虑可以调用成员函数的对象类型时,这是逻辑的工作方式。


再说一下漏洞,这里有一个例子(见马,没有演员表!

#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;
}