在C++中确定类构造函数参数的数量和类型?

Ser*_* K. 2 c++ templates constructor preprocessor auto-generate

如何确定类构造函数参数的数量和类型?为成员函数执行此操作只是小菜一碟:

template <class T, typename P0, typename P1, typename P2, typename P3>
void BindNativeMethod( void (T::*MethodPtr)(P0, P1, P2, P3) )
{
   // we've got 4 params
   // use them this way:
   std::vector<int> Params;
   Params.push_back( TypeToInt<P0>() );
   Params.push_back( TypeToInt<P1>() );
   Params.push_back( TypeToInt<P2>() );
   Params.push_back( TypeToInt<P3>() );
}

template <class T, typename P0, typename P1, typename P2, typename P3, typename P4>
void BindNativeMethod( void (T::*MethodPtr)(P0, P1, P2, P3, P4) )
{
   // we've got 5 params
   // use them this way:
   std::vector<int> Params;
   Params.push_back( TypeToInt<P0>() );
   Params.push_back( TypeToInt<P1>() );
   Params.push_back( TypeToInt<P2>() );
   Params.push_back( TypeToInt<P3>() );
   Params.push_back( TypeToInt<P4>() );
}
Run Code Online (Sandbox Code Playgroud)

等等其他成员.

但是如何处理类构造函数呢?有没有办法找出他们的论点类型?也许有一种根本不同的方法来解决这个问题,因为甚至不可能采用构造函数的地址?

编辑:我有一个C++预处理器,它扫描所有源文件,并拥有所有类,方法,ctors及其确切原型的数据库.我需要基于此生成一些存根.

jxh*_*jxh 5

如果我正确理解了您的要求,您需要一个函数,您可以使用它的地址告诉您构造函数或构造函数的参数类型.

#include <string>
#include <new>

template <typename T, typename P0, typename P1>
T * fake_ctor (T *mem, P0 p0, P1 p1) {
    return mem ? new (mem) T(p0, p1) : 0;
}

struct Foo {
    Foo (int, int) {}
    Foo (int, std::string) {}
};

template <class T, typename P0, typename P1>
void BindClassCtor(T *(*FakeCtor)(T *, P0, P1)) {
    std::vector<int> Params;
    Params.push_back( TypeToInt<P0>() );
    Params.push_back( TypeToInt<P1>() );
}

// PARSER GENERATED CALLS
BindClassCtor<Foo, int, int>(&fake_ctor);
BindClassCtor<Foo, int, std::string>(&fake_ctor);
Run Code Online (Sandbox Code Playgroud)

实现fake_ctor实际调用ctor(即使它fake_ctor本身永远不会被调用)提供了一定程度的编译时间健全性.如果Foo更改其中一个构造函数而不重新生成BindClassCtor调用,则可能会导致编译时错误.

编辑:作为奖励,我使用具有可变参数的模板简化了参数绑定.首先,BindParams模板:

template <typename... T> struct BindParams;

template <typename T, typename P0, typename... PN>
struct BindParams<T, P0, PN...> {
    void operator () (std::vector<int> &Params) {
        Params.push_back( TypeToInt<P0>() );
        BindParams<T, PN...>()(Params);
    }
};

template <typename T>
struct BindParams<T> {
    void operator () (std::vector<int> &Params) {}
};
Run Code Online (Sandbox Code Playgroud)

现在,fake_ctor它现在是一个类的集合,因此每个类都可以通过一个可变参数列表进行实例化:

template <typename... T> struct fake_ctor;

template <typename T>
class fake_ctor<T> {
    static T * x (T *mem) {
        return mem ? new (mem) T() : 0;
    }
    decltype(&x) y;
public:
    fake_ctor () : y(x) {}
};

template <typename T, typename P0>
class fake_ctor<T, P0> {
    static T * x (T *mem, P0 p0) {
        return mem ? new (mem) T(p0) : 0;
    }
    decltype(&x) y;
public:
    fake_ctor () : y(x) {}
};

template <typename T, typename P0, typename P1>
class fake_ctor<T, P0, P1> {
    static T * x (T *mem, P0 p0, P1 p1) {
        return mem ? new (mem) T(p0, p1) : 0;
    }
    decltype(&x) y;
public:
    fake_ctor () : y(x) {}
};
Run Code Online (Sandbox Code Playgroud)

现在粘合剂功能就是这样:

template <typename... T>
void BindClassCtor (fake_ctor<T...>) {
    std::vector<int> Params;
    BindParams<T...>()(Params);
}
Run Code Online (Sandbox Code Playgroud)

下面是构造函数参数绑定的说明,Bar它有四个构造函数.

struct Bar {
    Bar () {}
    Bar (int) {}
    Bar (int, int) {}
    Bar (int, std::string) {}
};

BindClassCtor(fake_ctor<Bar>());
BindClassCtor(fake_ctor<Bar, int>());
BindClassCtor(fake_ctor<Bar, int, int>());
BindClassCtor(fake_ctor<Bar, int, std::string>());
Run Code Online (Sandbox Code Playgroud)