C++ 获取与模板arg中传递的函数成员类型相同的类

C++ 获取与模板arg中传递的函数成员类型相同的类,c++,templates,function-pointers,C++,Templates,Function Pointers,当我将派生类的函数成员指针作为模板参数传递时,我正在尝试但不知道如何(但可能是不可能的)捕获相同类型的类 比如说,有了这段代码 class CObject{ public: string m_id; void setID(const char * id){ printf("assign id %s\n",id); m_id=string(id); } ~CObject(){} }; class CDerivedObjec

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

比如说,有了这段代码

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());
}
如果我用g++(我的上一个版本是5.4.0)编译这段代码,它会打印出7CObject,这意味着它是CObject类型,但在我传递的参数中,CDerivedObject::setID。我知道函数setID函数属于CObject,因此编译器以这种方式获取类型,但是

是否有一种可能的方法来捕获我传递给模板参数的类类型(即,不是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)
是一种解决方案,但我更喜欢模板而不是宏。

考虑以下程序:

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] > _
不完全是,编译器(或者至少是我的g++编译器)将其视为&CObject::setID而不是&CDerivedObject::setID。不要忘记为cv限定成员函数、ref限定成员函数以及C++17中的noexcept成员函数重载函数。或者,根据您所做的工作,您可以使用一个表示整个成员函数类型指针的参数,只需使用
std::is_member_function_pointer
。在发布之前是否尝试过您的解决方案?@cheers-sandhth.-Alf。对为什么?它不会编译吗?@JordiEspada:它会编译,但模板参数
\u C
与成员函数指针类型无关,这与以前相同。我不明白您的示例@Cheers和htl的意思。我要问的是,是否有一种方法可以捕获传递到模板中的类类型。在本例中,我传递的是CDerivedObject::setID,但它将模板视为CObject::setID,所以它是CObject而不是CDerivedObject。@Jordi:这意味着传递的是一个
空(CObject::*)(char const*)
。模板匹配准确地拾取您正在传递的类型。
function\u template\u test(&CDerivedObject::setID)否则@水飲み鳥: 不完全是,但在那个方向是的。要明确指定类型,必须为模板参数指定类型,这些参数是
\u R
\u T
\u A
@cheers和hth.-Alf,但不能在该调用中推导出
\u A
?我的意思是,你必须提供最后一个不能推断的类型参数,不是吗?
struct Base { void foo() {} };
struct Derived: Base {};

auto main() -> int
{
    int x = &Derived::foo;
}
[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] > _
#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;
}