【发布时间】:2015-06-16 04:19:59
【问题描述】:
我有以下代码:
int main(int argc, char **argv)
{
App app(800, 600);
app.add_event_scene(Scene("Event Plot", event_plot));
Image x("sample.png");
struct foo { static void visual_plot() { x.draw(); } }; // Error.
app.add_visual_scene(Scene("Visual Plot", foo::visual_plot));
app.run();
return 0;
}
我收到以下错误:
||=== Build: Debug in Joy-Plus-Plus (compiler: GNU GCC Compiler) ===|
G:\Development\Game-Development\CB\Joy-Plus-Plus\main.cpp|54|error: use of local variable with automatic storage from containing function|
G:\Development\Game-Development\CB\Joy-Plus-Plus\main.cpp|53|error: 'Image x' declared here|
||=== Build failed: 2 error(s), 0 warning(s) (0 minute(s), 0 second(s)) ===|
I'm writing a multimedia/game engine 用于Allegro 5 library,我已经将主循环的绘图部分(以及事件部分)抽象为带有绘图(函数)的“场景”对象。每个过程都被传递给应用程序,以便它在主循环中“运行”。问题是,“C++ 方法”不起作用:
Image x("sample.png");
void visual_plot()
{
x.draw(); // Problem.
}
int main(int argc, char **argv)
{
App app(800, 600);
app.add_event_scene(Scene("Event Plot", event_plot));
app.add_visual_scene(Scene("Visual Plot", visual_plot));
app.run();
return 0;
}
虽然代码运行了,但还是会发生这种情况:
如果我把 x 放在 visual_plot 里面,图片就会正常加载:
但是现在我遇到了一个巨大的性能问题,因为在每个主循环中都会创建一个新的 Image 对象(而且不久之后整个事情就会冻结)。
当我把它放在函数范围之外时找不到图像,因为 它必须 在应用程序初始化之后出现,但是因为我在 Scene 中有一个 typedef 函数指针,它采用该函数作为一个论点,我也必须给它一个 void 函数。问题是我无法在 C++ 中创建本地/嵌套函数(在应用程序初始化之后)。所以,为了避免这个问题,我尝试了明显的(Lambda表达式/闭包):
int main(int argc, char **argv)
{
App app(800, 600);
app.add_event_scene(Scene("Event Plot", event_plot));
Image x("sample.png");
app.add_visual_scene(Scene("Visual Plot", [&x]()->void{x.draw();}));
app.run();
return 0;
}
问题是Scene的构造函数的第二个参数带了一个函数指针:
typedef void(*plot)();
typedef map<string, plot> act;
class Scene
{
private:
string name;
plot p;
public:
Scene(string name, plot p);
~Scene() {};
string get_name();
plot get_plot();
void set_name(string value);
void set_plot(plot value);
};
由于函数不能作为参数传递,并且会衰减为指针,因此同样适用于 lambda 表达式(它不是函数),所以我收到以下错误:
G:\Development\Game-Development\CB\Joy-Plus-Plus\main.cpp|52|error: no matching function for call to 'Scene::Scene(const char [12], main(int, char**)::__lambda0)'|
面对这样的悲剧,如何在C++11中模拟嵌套函数? Since simulating like this answer 不起作用。
OBS:我同意这可能是一个设计问题,但我几乎不这么认为。对我来说,C++ 只是不希望我以任何方式将那个该死的函数作为参数传递(所以,我请求各位 C++ 专家的帮助)。
【问题讨论】:
-
将
Image x("sample.png");移动到visual_plot中并使其变为static?或者,将std::function<void()>用作plot,而不是函数指针。 -
我不能把
Image x("sample.png");放在visual_plot过程中,因为这会冻结应用程序(Since visual_plot is being run at each_frame in a main_loop) -
"并使其成为
static"(静态局部只初始化一次,第一次调用该函数)。 -
@Praetorian OP 确实说 “当我把它放在函数范围之外时找不到图像,因为它必须在应用程序初始化之后出现” 虽然我你在文字和图片墙上错过了它并不奇怪:)
-
如果您有大量图像,请将它们全部放入您在全局
unique_ptr中保存的结构中,并在创建App后将它们全部初始化。然后进行初始化可能会更好,否则您会有一种“即时”初始化,当您不准备处理它时可能会失败。
标签: c++ function c++11 lambda allegro