std :: function分配在Visual C ++ 2015 Win32应用程序中不起作用

时间:2018-12-06 13:24:37

标签: c++ winapi

这是我的情况:

main.cpp

#include <Windows.h>
#include <functional>

std::function<void()> OnPrepare;

int WINAPI WinMain(HINSTANCE inst, HINSTANCE preInst, TCHAR*, int) {
    if (OnPrepare) {
        OnPrepare();
    }

    return 0;
}

other.cpp

#define _AFXDLL
#include <afx.h>  // TRACE
#include <functional>

extern std::function<void()> OnPrepare;

class Init {
public:
    Init() {
        OnPrepare = []() {
            TRACE("hello, world!\n");
        };
    }
};

Init g_init;

此代码在Win32应用程序中不起作用,但在控制台应用程序中则很好。我不知道为什么谁能指出我的代码出了什么问题?如果我不能这样做,还有更好的方法吗?

编辑:

OnPrepare在Win32应用程序中始终为null,因此不会出现"hello, world"

1 个答案:

答案 0 :(得分:2)

用于构建的代码g_init修改了OnPrepare。当然,只有在OnPrepare已被构造的情况下,这才是合法的。但是,如果g_init是在OnPrepare之前构造的呢?然后,您将修改尚未构造的对象,然后再构造已经修改的对象。哎哟。在静态对象的构造函数中进行实际工作绝不是一个好主意。

目前尚不清楚您的外部问题是什么,但是此代码不是解决此问题的好方法。一个丑陋的解决方法是将全局std::function替换为返回对静态静态std::function的引用的全局函数并使用它。这样可以确保在将对象分配给对象之前对其进行构造。

std::function<void()>& getOnPrepare()
{
    static std::function<void()> OnPrepare;
    return OnPrepare;
}

然后,Init的构造函数可以调用getOnPrepare,确保在将OnPrepare分配给以下对象之前对其进行构造:

Init() {
    getOnPrepare() = []() {
        TRACE("hello, world!\n");
    };