如何传递指向构造函数的函数指针?

Kar*_*eem 33 c++ reflection constructor function-pointers

我正在努力在C++中实现一个反射机制.我的代码中的所有对象都是Object的子类(我自己的泛型类型),它包含类型为Class的静态成员数据.

class Class{
public:
   Class(const std::string &n, Object *(*c)());
protected:
   std::string name;     // Name for subclass
   Object *(*create)();  // Pointer to creation function for subclass
};
Run Code Online (Sandbox Code Playgroud)

对于具有静态Class成员数据的Object的任何子类,我希望能够使用指向该子类的构造函数的指针初始化'create'.

Mic*_*urr 58

您不能获取构造函数的地址(C++ 98 Standard 12.1/12 Constructors - "12.1-12 Constructors - "不应该使用构造函数的地址.)

您最好的办法是拥有一个工厂函数/方法来创建Object并传递工厂的地址:

class Object;

class Class{
public:
   Class(const std::string &n, Object *(*c)()) : name(n), create(c) {};
protected:
   std::string name;     // Name for subclass
   Object *(*create)();  // Pointer to creation function for subclass
};

class Object {};

Object* ObjectFactory()
{
    return new Object;
}



int main(int argc, char**argv)
{
    Class foo( "myFoo", ObjectFactory);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

  • 使它成为模板将使它实际返回"Class":template <typename T> Object*ObjectFactory(){return new T; } ....类foo("myFoo",&ObjectFactory <Class>); (5认同)

小智 7

我遇到了同样的问题。我的解决方案是一个调用构造函数的模板函数。

template<class T> MyClass* create()
{
    return new T;
}
Run Code Online (Sandbox Code Playgroud)

将其用作函数指针很简单:

MyClass* (*createMyClass)(void) = create<MyClass>;
Run Code Online (Sandbox Code Playgroud)

并获取 MyClass 的实例:

MyClass* myClass = createMyClass();
Run Code Online (Sandbox Code Playgroud)


lam*_*345 6

拉姆达风格:

[](){return new YourClass();}
Run Code Online (Sandbox Code Playgroud)

  • 请考虑为此添加更多解释/上下文,因为这会使答案对未来的读者更有用。 (2认同)

bra*_*ing 5

使用可变参数模板,您可以创建一个包装器,它将构造函数变成函子。

#include <utility>

template <typename T>
struct BindConstructor{
    template<typename... Args>
    T operator()(Args&&...args)const{
        return T(std::forward<Args>(args)...);
    }
};


struct Foo {
    Foo(int a, int b):a(a),b(b){}
    int a;
    int b;
};

template <typename Fn>
auto Bar(Fn f){
    return f(10,20);
}

int main(){
    Foo foo = Bar(BindConstructor<Foo>());
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/5W383McTc