我是从无法控制的基类派生一个类。该类将由我传入的工厂函数指针创建(在我也不控制的部分代码中)。
在派生类中,我需要向工厂函数传递一个附加的构造函数参数。
我的第一个选项是尝试通过lambda来适应工厂功能,但这无法捕获其他参数。其他答案解释了为什么这行不通。接下来,我尝试用std::function
来补充该问题,其他答案使我相信它可以起作用,但是我无法找出正确的语法,并且发现这些示例令人难以理解(并且不确定我是否真的理解那个例子)甚至还在做)。
我在这里做错了什么?有没有更好的方法来解决这个问题?
演示代码:
#include <functional>
#include <string>
// I have no control over this
struct Base {
Base(int i) {}
};
void UseObject(Base *(*factory)(int i)) {
Base *instance = factory(5);
// Save created instance
}
// I control the rest
struct Derived : public Base {
Derived(const char *s, int i) : Base(i) { /* Store s for later use */ }
static Base *Factory(const char *s, int i) { return new Derived(s, i); }
};
void AddObject(const char *name)
{
// First stab
// UseObject([name] (int i) { return Derived::Factory(name, i); });
// Second stab
std::function<Base *(int i)> foo { [name] (int i) { return Derived::Factory(name, i); } };
UseObject(foo);
}
int main(int ac, char **av)
{
AddObject("some_name");
AddObject("another_name");
return 0;
}
我从g ++(7.4.0)得到的错误是:
tfunc.cpp: In function ‘void AddObject(const char*)’:
tfunc.cpp:28:18: error: cannot convert ‘std::function<Base*(int)>’ to ‘Base* (*)(int)’ for argument ‘1’ to ‘void UseObject(Base* (*)(int))’
UseObject(foo);
UseObject
不允许不捕获lambda或std::function
或常规类函子。它接受的唯一可调用对象是函数指针(无法捕获的lambda可以转换为)。
所以您可以这样做:
UseObject([](int i) { return Derived::Factory("some_name", i); });
但不是
auto name = "some_name";
UseObject([name] (int i) { return Derived::Factory(name, i); });
可能的(有限的)解决方法是使用全局变量来存储状态。 (因此不能同时使用。)>
void AddObject(const char *name)
{
// global usage as UseObject only accepts pointer function
static const char* instance = nullptr;
instance = name;
UseObject(+[](int i) { return Derived::Factory(instance, i); });
}